首页 > 解决方案 > 查询时如何正确设置json的嵌套dict路径

问题描述

我收到错误消息:

Exception has occurred: KeyError
'Key not exists'
  File "C:\ShopFloor\main.py", line 59, in main
    res = qe.at('vehicledata.result.NUM').where('Status', '=', 1).where('Process', '=', 'SPA').get()
  File "C:\ShopFloor\main.py", line 96, in <module>
    main()

...在以下行中:

qe = JsonQ(r"C:\ShopFloor\data.json")
res = qe.at('vehicledata.result.NUM').where('Status', '=', 1).where('Process', '=', 'SPA').get()      
pprint(res)
JsonQ.reset(qe)

vehicledata 是一个字符串,但是 result.NUM 是动态的,因此 result.NUM 有大约 2000 个不同的字典。我的查询旨在获取所有状态为 1 且进程为 SPA 的数字:我怎样才能让它工作?我认为这是由于动态 dict 任何帮助表示赞赏

这是来自 data.json 的小样本数据

{
    "vehicledata": [
        {
            "12345678901234567": {
                "Process": "SPA",
                "Status": 0
            }
        },
        {
            "12345678901234567": {
                "Process": "Road",
                "Status": 0
            }
        },

标签: pythonjsonjsonq

解决方案


根据您提供的jsonq 文档示例,您需要将代码更改为以下内容:

from pyjsonq import JsonQ
from pprint import pprint
import json


qe = JsonQ("data.json")

res = qe.at('vehicledata').get()
l = list(map(lambda r: r.values()[0], res))
d = {"vehicledata": l}
with open('extarcted_data.json', 'wb') as outfile:
    json.dump(d, outfile)

q = JsonQ("extarcted_data.json")
r = q.at('vehicledata').where('Status', '=', 1).where('Process', '=', 'SPA').get()
print(r)

JsonQ.reset(q)
JsonQ.reset(qe)

这个想法是跟随你采取所有可以改变的元素vehicledata和你需要的对象。使用标准json库并将之前的对象包装到新的对象中,无需额外的层。之后JsonQ使用方便搜索。上面的代码是概念证明,可能不是最好的解决方案。根据文档JsonQ不允许跳过层,您必须知道您的密钥才能检索数据。在您的情况下,您将必须知道12345678901234567或任何代替它的数字。

替代解决方案

该解决方案使使用变得JsonQ可疑。尽管如此,我还是把它贴在这里作为参考:

from pyjsonq import JsonQ
from pprint import pprint


qe = JsonQ("data.json")
objs = qe.at('vehicledata').get()

for obj in objs:
    values = obj.values()[0]
    if 'Status' in values and values['Status'] == 1 and 'Process' in values and values['Process'] == 'SPA':
        pprint(values)

JsonQ.reset(qe)

推荐阅读