Объедините несколько файлов JSONL из папки с помощью Python

#python #json #merge #etl #jsonlines

Вопрос:

Я ищу решение для объединения нескольких файлов JSONL из одной папки с помощью скрипта Python. Что-то вроде приведенного ниже сценария, который работает для файлов JSON.

 import json
import glob

result = []
for f in glob.glob("*.json"):
    with jsonlines.open(f) as infile:
        result.append(json.load(infile))

with open("merged_file.json", "wb") as outfile:
     json.dump(result, outfile)

 

Пожалуйста, найдите ниже образец моего файла JSONL(только одна строка). :

 {"date":"2021-01-02T08:40:11.378000000Z","partitionId":"0","sequenceNumber":"4636458","offset":"1327163410568","iotHubDate":"2021-01-02T08:40:11.258000000Z","iotDeviceId":"text","iotMsg":{"header":{"deviceTokenJwt":"text","msgType":"text","msgOffset":3848,"msgKey":"text","msgCreation":"2021-01-02T09:40:03.961 01:00","appName":"text","appVersion":"text","customerType":"text","customerGroup":"Customer"},"msgData":{"serialNumber":"text","machineComponentTypeId":"text","applicationVersion":"3.1.4","bootloaderVersion":"text","firstConnectionDate":"2018-02-20T10:34:47 01:00","lastConnectionDate":"2020-12-31T12:05:04.113 01:00","counters":[{"type":"DurationCounter","id":"text","value":"text"},{"type":"DurationCounter","id":"text","value":"text"},{"type":"DurationCounter","id":"text","value":"text"},{"type":"IntegerCounter","id":"text","value":2423},{"type":"IntegerCounter","id":"text","value":9914},{"type":"DurationCounter","id":"text","value":"text"},{"type":"IntegerCounter","id":"text","value":976},{"type":"DurationCounter","id":"text","value":"PT0S"},{"type":"IntegerCounter","id":"text","value":28},{"type":"DurationCounter","id":"text","value":"PT0S"},{"type":"DurationCounter","id":"text","value":"PT0S"},{"type":"DurationCounter","id":"text","value":"text"},{"type":"IntegerCounter","id":"text","value":1}],"defects":[{"description":"ProtocolDb.ProtocolIdNotFound","defectLevelId":"Warning","occurrence":3},{"description":"BridgeBus.CrcError","defectLevelId":"Warning","occurrence":1},{"description":"BridgeBus.Disconnected","defectLevelId":"Warning","occurrence":6}],"maintenanceEvents":[{"interventionId":"Other","comment":"text","appearance_display":0,"intervention_date":"2018-11-29T09:52:16.726 01:00","intervention_counterValue":"text","intervention_workerName":"text"},{"interventionId":"Other","comment":"text","appearance_display":0,"intervention_date":"2019-06-04T15:30:15.954 02:00","intervention_counterValue":"text","intervention_workerName":"text"}]}}}

 

Кто-нибудь знает, как я могу справиться с этой загрузкой?

Ответ №1:

Вы можете обновлять основной диктант с каждым загружаемым объектом json. Нравится

 import json
import glob

result = {}
for f in glob.glob("*.json"):
    with jsonlines.open(f) as infile:
        result.update(json.load(infile)) #merge the dicts

with open("merged_file.json", "wb") as outfile:
     json.dump(result, outfile)
 

Но это перехитрит аналогичные ключи.!

Комментарии:

1. Когда я запускаю ваш код, я получаю эту ошибку : EOFError

Ответ №2:

Поскольку каждая строка в файле JSONL является полным объектом JSON, на самом деле вам вообще не нужно анализировать файлы JSONL, чтобы объединить их в другой файл JSONL. Вместо этого объедините их, просто объединив. Однако предостережение здесь заключается в том, что формат JSONL не требует ввода символа новой строки в конце файла. Поэтому вам придется считывать каждую строку в буфер, чтобы проверить, заканчивается ли файл JSONL без символа новой строки, и в этом случае вам придется явно выводить символ новой строки, чтобы отделить первую запись следующего файла:

 with open("merged_file.json", "w") as outfile:
    for filename in glob.glob("*.json"):
        with open(filename) as infile:
            for line in infile:
                outfile.write(line)
            if not line.endswith('n'):
                outfile.write('n')
 

Комментарии:

1. Спасибо @blhsing за ваш ответ, но, к сожалению, я не получаю правильные данные(пропущенные строки)!

2. Затем, пожалуйста, обновите вопрос образцом ваших входных файлов.

3. Мне нравится этот ответ, но если в каком-либо из файлов jsonl в конце отсутствует новая строка, вы получите недостающие строки. Вероятно, вам придется обрабатывать строку за строкой, чтобы увидеть, есть ли там последняя новая строка.

4. @tdelaney, Ах, спасибо. Я не понимал, что JSONL позволяет завершать файл без символа новой строки. Затем обновил ответ соответствующим образом.

5. @Arvind, Если я не неправильно понял вопрос операции, я думаю, что операция означает объединение файлов JSONL в другой файл JSONL, а не в файл JSON.