PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Créer/insérer Json dans Postgres avec les requêtes et psycopg2

Il semble que vous vouliez créer une table avec une colonne nommée "data" . Le type de cette colonne est JSON. (Je recommanderais de créer une colonne par champ, mais c'est à vous de décider.)

Dans ce cas la variable data (qui est lu à partir de la requête) est une list de dict s. Comme je l'ai mentionné dans mon commentaire, vous pouvez boucler sur data et faites les insertions une par une comme executemany() n'est pas plus rapide que plusieurs appels à execute() .

Voici ce que j'ai fait :

  1. Créez une liste des champs qui vous intéressent.
  2. Boucle sur les éléments de data
  3. Pour chaque item dans data , extrayez les champs dans my_data
  4. Appelez execute() et transmettez json.dumps(my_data) (Convertit my_data d'un dict dans une chaîne JSON)

Essayez ceci :

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

Je ne suis pas sûr à 100 % si toute la syntaxe postgres est correcte ici (je n'ai pas accès à une base de données PG pour tester), mais je pense que cette logique devrait fonctionner pour ce que vous essayez de faire.

Mise à jour pour les colonnes séparées

Vous pouvez modifier votre instruction de création pour gérer plusieurs colonnes, mais cela nécessiterait de connaître le type de données de chaque colonne. Voici un pseudo-code que vous pouvez suivre :

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

Remplacez le ... avec les valeurs appropriées pour vos données.