PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Crea/Inserisci Json in Postgres con richieste e psycopg2

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:

  1. Crea un elenco di campi che ti interessano.
  2. Esegui il ciclo degli elementi di data
  3. Per ogni item in data , estrai i campi in my_data
  4. Chiama execute() e passa json.dumps(my_data) (Converte my_data da un dict 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.