在Python中将JSON转换为分行的JSON

28

我的目标是将JSON文件转换为可使用Python从Cloud Storage上传到BigQuery的格式(如此描述)。

我尝试使用 newlineJSON 软件包进行转换,但出现以下错误。

JSONDecodeError: Expecting value or ']': line 2 column 1 (char 5)

有人有解决这个问题的方法吗?

这里是示例JSON代码:

[{
    "key01": "value01",
    "key02": "value02",
    ...
    "keyN": "valueN"
},
{
    "key01": "value01",
    "key02": "value02",
    ...
    "keyN": "valueN"
},
{
    "key01": "value01",
    "key02": "value02",
    ...
    "keyN": "valueN"
}
]

这里是现有的Python脚本:

with nlj.open(url_samplejson, json_lib = "simplejson") as src_:
    with nlj.open(url_convertedjson, "w") as dst_:
        for line_ in src_:
            dst_.write(line_)

这是一个关于BigQuery的文档,其中包含了一个使用BigQuery客户端Python API将JSON加载到表格中的示例:https://googleapis.dev/python/bigquery/latest/generated/google.cloud.bigquery.client.Client.html#google.cloud.bigquery.client.Client.load_table_from_json - orpheus
5个回答

41

使用jq命令的答案确实很有用,但如果你还想使用Python(从问题中看起来是这样),你可以使用内置的json模块来做到。

import json
from io import StringIO
in_json = StringIO("""[{
    "key01": "value01",
    "key02": "value02",

    "keyN": "valueN"
},
{
    "key01": "value01",
    "key02": "value02",

    "keyN": "valueN"
},
{
    "key01": "value01",
    "key02": "value02",

    "keyN": "valueN"
}
]""")

result = [json.dumps(record) for record in json.load(in_json)]  # the only significant line to convert the JSON to the desired format

print('\n'.join(result))

{"key01": "value01", "key02": "value02", "keyN": "valueN"}
{"key01": "value01", "key02": "value02", "keyN": "valueN"}
{"key01": "value01", "key02": "value02", "keyN": "valueN"}

* 我这里只是使用StringIOprint来使样例更易于本地测试。

作为替代方案,您可以使用Python jq绑定另一个回答结合使用。


还适用于Python对象(而不是JSON字符串),如下所示:result = [json.dumps(item) for item in items] - Michael
5
我认为这是最佳答案。结合文件写入操作,我使用此答案生成以下代码片段: data = df.to_dict('records') output = open('test.json', 'w') output.write('\n'.join([json.dumps(record) for record in data])) output.close() - Conor Retra

25

如果您想离开Python,可以使用 jq

$ cat a.json 
[{
    "key01": "value01",
    "key02": "value02",
    "keyN": "valueN"
},
{
    "key01": "value01",
    "key02": "value02",
    "keyN": "valueN"
},
{
    "key01": "value01",
    "key02": "value02",
    "keyN": "valueN"
}
]


$ cat a.json | jq -c '.[]'
{"key01":"value01","key02":"value02","keyN":"valueN"}
{"key01":"value01","key02":"value02","keyN":"valueN"}
{"key01":"value01","key02":"value02","keyN":"valueN"}

我使用的迭代器是'.[]',用于遍历数组,并且-c参数将每个JSON对象放在单独的一行上。

资源:


非常高效的转换方法。在使用 jq 时会实现它。 - Fxs7576
你好,你是否也有执行相反操作的命令?从换行分隔符到格式良好的JSON数组 - Deviling Master
完美。但是一开始我错误地通过npm获取了jq,结果并不理想。 - bvj
在node.js中,我能够使用node-jq库来完成相同的操作。```jq.run('.[]','data.json',{output:'compact'}) .then((output)=> { dataStream.push(output) dataStream.push(null) dataStream.pipe(gcFile.createWriteStream({ resumable:false, validation:false, metadata:{'Cache-Control':'public,max-age = 31536000'} })) }) .catch((err)=> { console.log(err) })``` - Urvah Shabbir
你如何安装jq?根据链接的jq页面(https://stedolan.github.io/jq/download/),我应该“使用Chocolatey NuGet通过chocolatey install jq安装jq 1.5”-我以前从未听说过chocolatey,也不明白为什么需要安装更多东西才能获得jq? - J.D
https://pypi.org/project/jq/ pip install jq - Urvah Shabbir

13

这将把一个 JSON 文件转换为 ND-JSON 文件。

import json

with open("results-20190312-113458.json", "r") as read_file:
    data = json.load(read_file)
result = [json.dumps(record) for record in data]
with open('nd-proceesed.json', 'w') as obj:
    for i in result:
        obj.write(i+'\n')

希望这能对某人有所帮助。


1
这种方法可以轻松地适应编写流数据。 - denson
3
这将不会在嵌套对象内进行迭代。 - sa_penguin

0
with open('out.json', 'w') as f:
  for obj in objs:
    json.dump(obj, f)
    f.write('\n')

0
如果文件很大,你可能想使用一个更快的模块,比如msgspecorjson,因为它们使用c(或者c++,我不太确定,但它们更快)。
例子:
  • 读取
with open('test.json', 'rb') as f:
    j = msgspec.json.decode(f.read())
    
j = b'\n'.join(map(msgspec.json.encode, j))
with open('test.json', 'wb') as f:
    f.write(j)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接