#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.