【问题标题】:Extract Complex JSON提取复杂的 JSON
【发布时间】:2019-11-07 06:54:05
【问题描述】:

我想将一些 JSON 解析为 SQL INSERT,但是,由于数据的不同部分位于不同的级别,因此很难全部获取。

这是 JSON 文件:

{
"company_number":"01234567",
"data":{
    "address":{
        "address_line_1":"Fake street",
        "country":"England",
        "locality":"TRIAL",
        "postal_code":"### ###",
        "premises":"#"
    },
    "name":"Testing Testing",
    "name_elements":{
        "forename":"Test",
        "middle_name":"Testing",
        "surname":"Testing2",
        "title":"NEW"
    },
    "Nature_of_address":"Agriculture",
    "natures_of_control":["ownership-of-shares-50-to-75-percent"],
    "notified_on":"2016-04-06"
    }
} 

这是我目前使用的 Python 代码:

import os
import json

TABLE_NAME = "Holdingtbl"
sqlstatement = ''

test = []

#with open (Basenames,'r') as f:
#with open (json.dumps(x.to_table(), indent=4),'r') as f:
#    jsondata = json.loads(f.read())

#    print(jsondata)

for line in open('C:\\Users\\[Name]\\Desktop\\Test.json','r',encoding="utf-8"):
    test.append(json.loads(line))
    #print(test)

for json in test:
    keylist = "("
    valuelist = "("
    firstPair = True
    for key, value in json.items():
        if not firstPair:
            keylist += ", "
            valuelist += ", "
        firstPair = False
        keylist += key
        if type(value) in (str, "utf-8"):
            valuelist += "'" + value + "'"
        else:
            valuelist += str(value)
    keylist += ")"
    valuelist += ")"

    sqlstatement += "INSERT INTO " + TABLE_NAME + " " + keylist + " VALUES " + valuelist + "\n"

print(sqlstatement)

结果是:

INSERT INTO Holdingtbl (company_number, data) VALUES ('01234567', {'address': {'address_line_1': 'Fake street, 'country': 'England', 'locality': 'TRIAL', 'postal_code': '### ###', 'premises': ‘#'}, 'name': 'Testing Testing', 'name_elements': {'forename': 'Test', 'middle_name': 'Testing', 'surname': 'Testing2', 'title': 'New'},'Nature_of_address': 'Agriculture' ,'natures of control’: ['ownership-of-shares-50-to-75-percent'], 'notified_on': '2016-04-06'})

这有点对,但我需要插入看起来像:

INSERT INTO Holdingtbl (Company_number, address_line_1, country, locality, postal_code, premises, name, forename, middle_name, surname, title, nature_of_address, natures_of_control, notified_on) VALUES('01234567', 'Fake street', 'England', 'Trial', '### ###', '#', 'Testing Testing', 'Test', 'Testing', 'Testing2', 'New', 'Agriculture', 'ownership-of-shares-50-to-75-percent', '2016-01-06');

我见过一些例子: Example1

但我无法让它为我工作。

@Skaul05

我认为你的意思是:但它会导致错误:AttributeError: 'dict' object has no attribute 'iteritems'

import os
import json

TABLE_NAME = "Holdingtbl"
sqlstatement = ''

test = []
value = []
key = []
def get_value(json):
    for i,j in json.iteritems():
        if type(j) in (str, "utf-8"):
            key.append(i)
            value.append(j)
        elif type(j) == list:
            key.append(i)
            value.append(j[0])
        elif type(j) == dict:
            get_value(j)

#with open (Basenames,'r') as f:
#with open (json.dumps(x.to_table(), indent=4),'r') as f:
#    jsondata = json.loads(f.read())

#    print(jsondata)

for line in open(''C:\\Users\\[Name]\\Desktop\\Test.json'','r',encoding="utf-8"):
    test.append(json.loads(line))
    #print(test)

for json in test:
    get_value(json)

    sqlstatement += "INSERT INTO " + TABLE_NAME + " " + keylist + " VALUES " + valuelist + "\n"

print(sqlstatement)

如果我循环超过一个 json 行,这是输出:

        INSERT INTO Holdingtbl (company_number,address_line_1,address_line_2,country,locality,postal_code,premises,region,ceased_on,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('08581893','High Street','Wendover','England','Aylesbury','HP22 6EA','14a','Buckinghamshire','2016-07-01','England','d55168c49f85ab1ef38a12ed76238d68f79f5a01','individual-person-with-significant-control','/company/08581893/persons-with-significant-control/individual/-6HQmkhiomEBXJI2rgHccU67fpM','Mr Quentin Colin Maxwell Solt','Quentin','Colin Maxwell','Solt','Mr','British','ownership-of-shares-25-to-50-percent','2016-06-30');
        INSERT INTO Holdingtbl (company_number,address_line_1,address_line_2,country,locality,postal_code,premises,region,ceased_on,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('08581893','High Street','Wendover','England','Aylesbury','HP22 6EA','14a','Buckinghamshire','2016-07-01','England','d55168c49f85ab1ef38a12ed76238d68f79f5a01','individual-person-with-significant-control','/company/08581893/persons-with-significant-control/individual/-6HQmkhiomEBXJI2rgHccU67fpM','Mr Quentin Colin Maxwell Solt','Quentin','Colin Maxwell','Solt','Mr','British','ownership-of-shares-25-to-50-percent','2016-06-30');
    INSERT INTO Holdingtbl (company_number,address_line_1,address_line_2,country,locality,postal_code,premises,region,ceased_on,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on,company_number,address_line_1,address_line_2,locality,postal_code,region,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('08581893','High Street','Wendover','England','Aylesbury','HP22 6EA','14a','Buckinghamshire','2016-07-01','England','d55168c49f85ab1ef38a12ed76238d68f79f5a01','individual-person-with-significant-control','/company/08581893/persons-with-significant-control/individual/-6HQmkhiomEBXJI2rgHccU67fpM','Mr Quentin Colin Maxwell Solt','Quentin','Colin Maxwell','Solt','Mr','British','ownership-of-shares-25-to-50-percent','2016-06-30','01605766','Wates House','Station Approach','Leatherhead','KT22 7SW','Surrey','England','16c4017adbe1919073fef3fad7535841299de14c','individual-person-with-significant-control','/company/01605766/persons-with-significant-control/individual/Z6tt_4IDQGaS5MU_wOCCCOj4zyY','Mr Jeremy Wyckham Wright','Jeremy','Wyckham','Wright','Mr','British','significant-influence-or-control','2016-06-29');
        INSERT INTO Holdingtbl (company_number,address_line_1,address_line_2,country,locality,postal_code,premises,region,ceased_on,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('08581893','High Street','Wendover','England','Aylesbury','HP22 6EA','14a','Buckinghamshire','2016-07-01','England','d55168c49f85ab1ef38a12ed76238d68f79f5a01','individual-person-with-significant-control','/company/08581893/persons-with-significant-control/individual/-6HQmkhiomEBXJI2rgHccU67fpM','Mr Quentin Colin Maxwell Solt','Quentin','Colin Maxwell','Solt','Mr','British','ownership-of-shares-25-to-50-percent','2016-06-30');

    INSERT INTO Holdingtbl (company_number,address_line_1,address_line_2,country,locality,postal_code,premises,region,ceased_on,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on,company_number,address_line_1,address_line_2,locality,postal_code,region,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('08581893','High Street','Wendover','England','Aylesbury','HP22 6EA','14a','Buckinghamshire','2016-07-01','England','d55168c49f85ab1ef38a12ed76238d68f79f5a01','individual-person-with-significant-control','/company/08581893/persons-with-significant-control/individual/-6HQmkhiomEBXJI2rgHccU67fpM','Mr Quentin Colin Maxwell Solt','Quentin','Colin Maxwell','Solt','Mr','British','ownership-of-shares-25-to-50-percent','2016-06-30','01605766','Wates House','Station Approach','Leatherhead','KT227SW','Surrey','England','16c4017adbe1919073fef3fad7535841299de14c','individual-person-with-significant-control','/company/01605766/persons-with-significant-control/individual/Z6tt_4IDQGaS5MU_wOCCCOj4zyY','Mr Jeremy Wyckham Wright','Jeremy','Wyckham','Wright','Mr','British','significant-influence-or-control','2016-06-29');
INSERT INTO Holdingtbl (company_number,address_line_1,address_line_2,country,locality,postal_code,premises,region,ceased_on,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on,company_number,address_line_1,address_line_2,locality,postal_code,region,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on,company_number,address_line_1,country,locality,postal_code,premises,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('08581893','High Street','Wendover','England','Aylesbury','HP22 6EA','14a','Buckinghamshire','2016-07-01','England','d55168c49f85ab1ef38a12ed76238d68f79f5a01','individual-person-with-significant-control','/company/08581893/persons-with-significant-control/individual/-6HQmkhiomEBXJI2rgHccU67fpM','Mr Quentin Colin Maxwell Solt','Quentin','Colin Maxwell','Solt','Mr','British','ownership-of-shares-25-to-50-percent','2016-06-30','01605766','Wates House','Station Approach','Leatherhead','KT22 7SW','Surrey','England','16c4017adbe1919073fef3fad7535841299de14c','individual-person-with-significant-control','/company/01605766/persons-with-significant-control/individual/Z6tt_4IDQGaS5MU_wOCCCOj4zyY','Mr Jeremy Wyckham Wright','Jeremy','Wyckham','Wright','Mr','British','significant-influence-or-control','2016-06-29','10259080','College Avenue','United Kingdom','Oldham','OL8 4DX','54','United Kingdom','231a5a1071ef608f60a79a0fce2c3e21e29f00b9','individual-person-with-significant-control','/company/10259080/persons-with-significant-control/individual/6Fkld0qaXyjm4FhJMsmUFKAJU4I','Dr Muhammad Fayaz Khan','Muhammad','Fayaz','Khan','Dr','British','ownership-of-shares-25-to-50-percent','2016-06-30');

我期待:

INSERT INTO Holdingtbl (company_number,address_line_1,address_line_2,country,locality,postal_code,premises,region,ceased_on,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('08581893','High Street','Wendover','England','Aylesbury','HP22 6EA','14a','Buckinghamshire','2016-07-01','England','d55168c49f85ab1ef38a12ed76238d68f79f5a01','individual-person-with-significant-control','/company/08581893/persons-with-significant-control/individual/-6HQmkhiomEBXJI2rgHccU67fpM','Mr Quentin Colin Maxwell Solt','Quentin','Colin Maxwell','Solt','Mr','British','ownership-of-shares-25-to-50-percent','2016-06-30');
INSERT INTO Holdingtbl (company_number,address_line_1,address_line_2,locality,postal_code,region,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('01605766','Wates House','Station Approach','Leatherhead','KT22 7SW','Surrey','England','16c4017adbe1919073fef3fad7535841299de14c','individual-person-with-significant-control','/company/01605766/persons-with-significant-control/individual/Z6tt_4IDQGaS5MU_wOCCCOj4zyY','Mr Jeremy Wyckham Wright','Jeremy','Wyckham','Wright','Mr','British','significant-influence-or-control','2016-06-29');
INSERT INTO Holdingtbl (company_number,address_line_1,country,locality,postal_code,premises,country_of_residence,etag,kind,self,name,forename,middle_name,surname,title,nationality,natures_of_control,notified_on) VALUES ('10259080','College Avenue','United Kingdom','Oldham','OL8 4DX','54','United Kingdom','231a5a1071ef608f60a79a0fce2c3e21e29f00b9','individual-person-with-significant-control','/company/10259080/persons-with-significant-control/individual/6Fkld0qaXyjm4FhJMsmUFKAJU4I','Dr Muhammad Fayaz Khan','Muhammad','Fayaz','Khan','Dr','British','ownership-of-shares-25-to-50-percent','2016-06-30');

【问题讨论】:

  • 如果它有助于文件的结构不应该改变。我得到一个巨大的 JSON 行列表,我需要对其进行迭代以创建插入语句。
  • 您是否希望将 json 展平以将单个字段放入数据库中?如果是这样,那么您需要将 json 读取为 dict,通过创建您提到的 SQL 来解析您需要输入数据库的字段。您不能将列表和字典提供给 SQL 插入。
  • 是的,我想展平 Json 文件。是这样的: for line in open('C:\\Users\[Name]\\Desktop\\Test.json','r',encoding="utf-8"): test.append(json.loads (行)) print test['data'] print test['data'][1]['address'][0]['Address_line_1']

标签: python json python-3.x


【解决方案1】:

递归可能是最适合这种情况的解决方案。

以下函数将在传递合适的 JSON 后为您的 sql 语句提供键和值列表。

value = []
key = []
def get_value(json):
    for i,j in json.items():
        if type(j) in (str, "utf-8"):
            key.append(i)
            value.append(j)
        elif type(j) == list:
            key.append(i)
            value.append(j[0])
        elif type(j) == dict:
            get_value(j)

然后你可以直接将它传递到你的 sql 语句中

sqlstatement +=  "INSERT INTO " + TABLE_NAME + " " + "(" + ",".join(key) + ")" + " VALUES " + "(" + ",".join(value) + ")" + ";"

输出:

INSERT INTO Holdingtbl (Nature_of_address,name,natures_of_control,surname,title,middle_name,forename,notified_on,premises,country,locality,postal_code,address_line_1,company_number) VALUES (Agriculture,Testing Testing,ownership-of-shares-50-to-75-percent,Testing2,NEW,Testing,Test,2016-04-06,#,England,TRIAL,### ###,Fake street,01234567);

希望这能回答你的问题!!!

【讨论】:

  • 我会让 json 等于什么?如果我尝试 get_value(json.loads(line)) 或 get_value(test) 我得到以下错误: AttributeError: 'list' object has no attribute 'iteritems', AttributeError: 'dict' object has no attribute 'iteritems'跨度>
  • 好的@Besarion 遍历列表并将每个项目传递给它。因此,您在问题中提到的 JSON 将其传递给 get_value。
  • 你的意思是此时迭代:for json in test 还是迭代:for key, value in json.items():提前道歉,我的 python 不是很好。
  • for json in test @Besarion 并将 json 传递给函数
  • 喜欢上面的?我添加到我在上面发布的原始位
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多