Sembra che tu voglia creare una tabella con una colonna denominata "data"
. Il tipo di questa colonna è JSON. (Consiglierei di creare una colonna per campo, ma dipende da te.)
In questo caso la variabile data
(che viene letto dalla richiesta) è un list
di dict
S. Come ho detto nel mio commento, puoi scorrere i data
ed esegui gli inserimenti uno alla volta come executemany()
non è più veloce di più chiamate a execute()
.
Quello che ho fatto è stato il seguente:
- Crea un elenco di campi che ti interessano.
- Esegui il ciclo degli elementi di
data
- Per ogni
item
indata
, estrai i campi inmy_data
- Chiama
execute()
e passajson.dumps(my_data)
(Convertemy_data
da undict
in una stringa JSON)
Prova questo:
#!/usr/bin/env python
import requests
import psycopg2
import json
conn = psycopg2.connect(database='NHL', user='postgres', password='postgres', host='localhost', port='5432')
req = requests.get('http://www.nhl.com/stats/rest/skaters?isAggregate=false&reportType=basic&isGame=false&reportName=skatersummary&sort=[{%22property%22:%22playerName%22,%22direction%22:%22ASC%22},{%22property%22:%22goals%22,%22direction%22:%22DESC%22},{%22property%22:%22assists%22,%22direction%22:%22DESC%22}]&cayenneExp=gameTypeId=2%20and%20seasonId%3E=20172018%20and%20seasonId%3C=20172018')
# data here is a list of dicts
data = req.json()['data']
cur = conn.cursor()
# create a table with one column of type JSON
cur.execute("CREATE TABLE t_skaters (data json);")
fields = [
'seasonId',
'playerName',
'playerFirstName',
'playerLastName',
'playerId',
'playerHeight',
'playerPositionCode',
'playerShootsCatches',
'playerBirthCity',
'playerBirthCountry',
'playerBirthStateProvince',
'playerBirthDate',
'playerDraftYear',
'playerDraftRoundNo',
'playerDraftOverallPickNo'
]
for item in data:
my_data = {field: item[field] for field in fields}
cur.execute("INSERT INTO t_skaters VALUES (%s)", (json.dumps(my_data),))
# commit changes
conn.commit()
# Close the connection
conn.close()
Non sono sicuro al 100% che tutta la sintassi di Postgres sia corretta qui (non ho accesso a un database PG da testare), ma credo che questa logica dovrebbe funzionare per quello che stai cercando di fare.
Aggiornamento per colonne separate
Puoi modificare la tua istruzione create per gestire più colonne, ma richiederebbe la conoscenza del tipo di dati di ciascuna colonna. Ecco alcuni pseudocodici che puoi seguire:
# same boilerplate code from above
cur = conn.cursor()
# create a table with one column per field
cur.execute(
"""CREATE TABLE t_skaters (seasonId INTEGER, playerName VARCHAR, ...);"""
)
fields = [
'seasonId',
'playerName',
'playerFirstName',
'playerLastName',
'playerId',
'playerHeight',
'playerPositionCode',
'playerShootsCatches',
'playerBirthCity',
'playerBirthCountry',
'playerBirthStateProvince',
'playerBirthDate',
'playerDraftYear',
'playerDraftRoundNo',
'playerDraftOverallPickNo'
]
for item in data:
my_data = [item[field] for field in fields]
# need a placeholder (%s) for each variable
# refer to postgres docs on INSERT statement on how to specify order
cur.execute("INSERT INTO t_skaters VALUES (%s, %s, ...)", tuple(my_data))
# commit changes
conn.commit()
# Close the connection
conn.close()
Sostituisci il ...
con i valori appropriati per i tuoi dati.