sql >> Base de Datos >  >> RDS >> PostgreSQL

Crear/Insertar Json en Postgres con solicitudes y psycopg2

Parece que desea crear una tabla con una columna llamada "data" . El tipo de esta columna es JSON. (Recomendaría crear una columna por campo, pero depende de usted).

En este caso la variable data (que se lee de la solicitud) es una list de dict s. Como mencioné en mi comentario, puede recorrer data y haga las inserciones una a la vez como executemany() no es más rápido que varias llamadas a execute() .

Lo que hice fue lo siguiente:

  1. Cree una lista de campos que le interesen.
  2. Recorra los elementos de data
  3. Para cada item en data , extraiga los campos en my_data
  4. Llamar a execute() y pase json.dumps(my_data) (Convierte my_data de un dict en una cadena JSON)

Prueba esto:

#!/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()

No estoy 100 % seguro de si toda la sintaxis de postgres es correcta aquí (no tengo acceso a una base de datos de PG para probar), pero creo que esta lógica debería funcionar para lo que está tratando de hacer.

Actualizar para columnas separadas

Puede modificar su declaración de creación para manejar múltiples columnas, pero requeriría conocer el tipo de datos de cada columna. Aquí tienes un pseudocódigo que puedes 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()

Reemplace el ... con los valores apropiados para sus datos.