Получение данных из вложенного json с использованием python

Я пытаюсь получить некоторые данные с правительственного веб-сайта и сохранить их в двух разных таблицах. Один будет содержать имена файлов и дату выпуска (давайте назовем это filename ), а другой будет содержать фактические данные и ключ для соединения с filename (давайте назовем это datasplit )

Эти данные поступают в файл JSON, который я сохранил с веб-страницы (для этого у меня нет API). Вот небольшой пример того, как выглядит файл JSON:

{
    "filename": [
        {
            "id": 2,
            "nome": "Societa' controllate di fatto dalla Presidenza del Consiglio dei Ministri e dai Ministeri",
            "aggiornamento": "04-02-2020",
            "datasplit": [
                {
                    "cf": "00081070591",
                    "den": "SIOG SOCIETA'ITALIANA OLEODOTTI DI GAETA SPA IN AMM.NE STRAORDINARIA",
                    "dm": "1513641600"
                },
                {
                    "cf": "00103540829",
                    "den": "INDUSTRIA SICILIANA ACIDO FOSFORICO S.P.A.IN LIQUIDAZIONE",
                    "dm": "1513641600"
                }
            ]
        },
        {
            "id": 1,
            "nome": "Enti o societa' controllate dalle Amministrazioni Centrali",
            "aggiornamento": "30-10-2019",
            "datasplit": [
                {
                    "cf": "00049100522",
                    "den": "MPS TENIMENTI POGGIO BONELLI E CHIGI SARACINI - SOC. AGRICOLA SPA",
                    "dm": "1513641600"
                },
                {
                    "cf": "00051010528",
                    "den": "SOCIETA' AGRICOLA SUVIGNANO S.R.L.",
                    "dm": "1513641600"
                }
            ]
        },
        {
            "id": 4,
            "nome": "Societa' quotate inserite nell'indice FTSE MIB della Borsa italiana",
            "aggiornamento": "19-12-2017",
            "datasplit": [
                {
                    "cf": "00079760328",
                    "den": "ASSICURAZIONI GENERALI S.P.A.",
                    "dm": "1513641600"
                },
                {
                    "cf": "00222620163",
                    "den": "FRENI BREMBO - SPA",
                    "dm": "1513641600"
                }
            ]
        }
    ]
}

Итак, что я хотел бы получить, это таблица filename с полями id, nome, aggiornamento и таблицы с datasplit с id, aggiornamento, cf, den, dm

До сих пор я получал файл JSON (сохраняя его локально) с веб-страницы и читал его в моей программе на python.

# this works
import json
sqlstatement = ''
with open('splitdata.json', 'r') as f: #this is where I saved the website content I want to Import
    jsondata = json.loads(f.read())

Я пытался создать что-то, что могло бы пройти через файл json и создать несколько SQL-запросов INSERT INTO table_name чтобы впоследствии выполнить их и, наконец, сохранить мои данные в базе данных.

Итак, моя проблема в том, как сначала прочитать вложенный JSON и как вставить данные в мою базу данных (если у вас есть лучшее решение, чем создание и запуск сценария SQL).

При попытке цикла внутри JSON кажется, что он находит только один элемент.

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

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

print(sqlstatement)

Я знаю, что код не является полным для генерации правильных операторов SQL, но мне нужна помощь, чтобы добраться до вложенной части JSON, поля datasplit . Может быть, это не трактуется как словарь? Если да, то как я могу это исправить?

Всего 2 ответа


Вы можете попытаться решить проблему, используя Pandas, которая имеет возможности SQL:

import pandas as pd

for key, val in json_data.items():
    df = pd.json_normalize(val)
    df = df.explode('datasplit')
    df[['cf', 'den', 'dm']] = df.datasplit.apply(pd.Series)
    df = df.drop('datasplit', axis=1)

    df.to_sql(<name>, <con>)

Вот как выглядит каждый datasplit ( df ):

   id                                               nome aggiornamento  
0   2  Societa' controllate di fatto dalla Presidenza...    04-02-2020   
0   2  Societa' controllate di fatto dalla Presidenza...    04-02-2020   
1   1  Enti o societa' controllate dalle Amministrazi...    30-10-2019   
1   1  Enti o societa' controllate dalle Amministrazi...    30-10-2019   
2   4  Societa' quotate inserite nell'indice FTSE MIB...    19-12-2017   
2   4  Societa' quotate inserite nell'indice FTSE MIB...    19-12-2017   

            cf                                                den          dm  
0  00081070591  SIOG SOCIETA'ITALIANA OLEODOTTI DI GAETA SPA I...  1513641600  
0  00103540829  INDUSTRIA SICILIANA ACIDO FOSFORICO S.P.A.IN L...  1513641600  
1  00049100522  MPS TENIMENTI POGGIO BONELLI E CHIGI SARACINI ...  1513641600  
1  00051010528                 SOCIETA' AGRICOLA SUVIGNANO S.R.L.  1513641600  
2  00079760328                      ASSICURAZIONI GENERALI S.P.A.  1513641600  
2  00222620163                                 FRENI BREMBO - SPA  1513641600 

Я не уверен, где вы застряли, но, возможно, вы не знакомы с тем, как работают словари?

jsondata['filename'] # has everything you want. you array of data.

# get the first element in the array
jsondata['filename'][0]
# result: {'id': 2, 'nome': "Societa' controllate di fatto dalla Presidenza del Consiglio dei Ministri e dai Ministeri", 'aggiornamento': ཀ-02-2020', 'datasplit': [{'cf': �', 'den': "SIOG SOCIETA'ITALIANA OLEODOTTI DI GAETA SPA IN AMM.NE STRAORDINARIA", 'dm': �'}, {'cf': �', 'den': 'INDUSTRIA SICILIANA ACIDO FOSFORICO S.P.A.IN LIQUIDAZIONE', 'dm': �'}]}

# second element 
jsondata['filename'][1]
# result: {'id': 1, 'nome': "Enti o societa' controllate dalle Amministrazioni Centrali", 'aggiornamento': ཚ-10-2019', 'datasplit': [{'cf': �', 'den': 'MPS TENIMENTI POGGIO BONELLI E CHIGI SARACINI - SOC. AGRICOLA SPA', 'dm': �'}, {'cf': �', 'den': "SOCIETA' AGRICOLA SUVIGNANO S.R.L.", 'dm': �'}]}

# access `datasplit` directly like 
jsondata['filename'][0]['datasplit']
# result: [{'cf': �', 'den': "SIOG SOCIETA'ITALIANA OLEODOTTI DI GAETA SPA IN AMM.NE STRAORDINARIA", 'dm': �'}, {'cf': �', 'den': 'INDUSTRIA SICILIANA ACIDO FOSFORICO S.P.A.IN LIQUIDAZIONE', 'dm': �'}]


# or in for loop
for data in jsondata['filename']:
    data['datasplit']

Есть идеи?

10000