Parece que você deseja criar uma tabela com uma coluna chamada
"data"
. O tipo desta coluna é JSON. (Eu recomendaria criar uma coluna por campo, mas fica a seu critério.) Neste caso, a variável
data
(que é lido a partir da solicitação) é uma list
de dict
s. Como mencionei no meu comentário, você pode fazer um loop sobre data
e faça as inserções uma de cada vez como executemany()
não é mais rápido do que várias chamadas para execute()
. O que eu fiz foi o seguinte:
- Crie uma lista de campos importantes para você.
- Percorrer os elementos de
data
- Para cada
item
emdata
, extraia os campos emmy_data
- Chame
execute()
e passejson.dumps(my_data)
(Convertemy_data
de umdict
em uma string JSON)
Tente isto:
#!/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()
Não tenho 100% de certeza se toda a sintaxe do postgres está correta aqui (não tenho acesso a um banco de dados PG para testar), mas acredito que essa lógica deve funcionar para o que você está tentando fazer.
Atualização para colunas separadas
Você pode modificar sua instrução create para lidar com várias colunas, mas seria necessário conhecer o tipo de dados de cada coluna. Aqui está algum pseudocódigo que você pode seguir:
# 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()
Substitua o
...
com os valores apropriados para seus dados.