PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Erstellen/Einfügen von Json in Postgres mit Anfragen und psycopg2

Anscheinend möchten Sie eine Tabelle mit einer Spalte namens "data" erstellen . Der Typ dieser Spalte ist JSON. (Ich würde empfehlen, eine Spalte pro Feld zu erstellen, aber es liegt an Ihnen.)

In diesem Fall die Variable data (das aus der Anfrage gelesen wird) ist eine list von dict s. Wie ich in meinem Kommentar erwähnt habe, können Sie data durchlaufen und führen Sie die Einfügungen nacheinander als executemany() aus ist nicht schneller als mehrere Aufrufe von execute() .

Folgendes habe ich getan:

  1. Erstellen Sie eine Liste mit Feldern, die Ihnen wichtig sind.
  2. Schleifen Sie die Elemente von data
  3. Für jeden item in data , extrahieren Sie die Felder in my_data
  4. Rufen Sie execute() auf und übergeben Sie json.dumps(my_data) (Konvertiert my_data aus einem dict in einen JSON-String)

Versuchen Sie Folgendes:

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

Ich bin mir nicht 100 % sicher, ob die gesamte Postgres-Syntax hier korrekt ist (ich habe keinen Zugriff auf eine PG-Datenbank zum Testen), aber ich glaube, dass diese Logik für das, was Sie versuchen, funktionieren sollte.

Für separate Spalten aktualisieren

Sie können Ihre create-Anweisung ändern, um mehrere Spalten zu verarbeiten, aber dazu müssten Sie den Datentyp jeder Spalte kennen. Hier ist ein Pseudocode, dem Sie folgen können:

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

Ersetzen Sie den ... mit den entsprechenden Werten für Ihre Daten.