web-dev-qa-db-fra.com

psycopg2 insert python dictionary as json

Je veux insérer un dictionnaire python en tant que json dans ma base de données postgresql (via python et psycopg2).

J'ai:

thedictionary = {'price money': '$1', 'name': 'Google', 'color': '', 'imgurl': 'http://www.google.com/images/nav_logo225.png', 'charateristics': 'No Description', 'store': 'google'}

cur.execute("INSERT INTO product(store_id, url, price, charecteristics, color, dimensions) VALUES (%d, %s, %s, %d, %s, %s)", (1,  'http://www.google.com', '$20', thedictionary, 'red', '8.5x11'))

Et cela donne le message d'erreur:

cur.execute ("INSERT INTO product (store_id, url, price, charecteristics, color, dimensions) VALUES (% d,% s,% s,% d,% s,% s)", (1, ' http://www.google.com ',' 20 $ ', le fictionnel,' rouge ',' 8.5x11 ')) psycopg2.ProgrammingError: impossible d'adapter le type' dict '

Je ne sais pas comment procéder à partir d'ici. Je ne trouve rien sur Internet sur la façon de faire exactement ce genre de chose et je suis très nouveau sur psycopg2.

20
Rorschach
cur.execute("INSERT INTO product(store_id, url, price, charecteristics, color, dimensions) VALUES (%s, %s, %s, %s, %s, %s)", (1,  'http://www.google.com', '$20', json.dumps(thedictionary), 'red', '8.5x11'))

Cela va résoudre ton problème. Cependant, vous devriez vraiment stocker des clés et des valeurs dans leurs propres colonnes séparées. Pour récupérer le dictionnaire, procédez comme suit:

cur.execute('select charecteristics from product where store_id = 1')
dictionary = json.loads(cur.fetchone()[0])
42
hd1

Vous pouvez utiliser psycopg2.extras.Json pour convertir dict en json que postgre accepte.

from psycopg2.extras import Json

thedictionary = {'price money': '$1', 
'name': 'Google', 'color': '', 'imgurl': 'http://www.google.com/images/nav_logo225.png', 'charateristics': 'No Description', 'store': 'google'}

item ={
    "store_id":1,
    "url": 'http://www.google.com', 
    "price":'$20', 
    "charecteristics":Json(thedictionary), 
    "color":'red', 
    "dimensions":'8.5x11'
}

def sql_insert(tableName, data_dict):
    '''
    INSERT INTO product (store_id,  url,  price,  charecteristics,  color,  dimensions)
    VALUES (%(store_id)s, %(url)s, %(price)s, %(charecteristics)s, %(color)s, %(dimensions)s );
    '''
    sql = '''
        INSERT INTO %s (%s)
        VALUES (%%(%s)s );
        '''   % (tableName, ',  '.join(data_dict),  ')s, %('.join(data_dict))
    return sql

tableName = 'product'
sql = sql_insert(tableName, item)

cur.execute(sql, item)

Pour plus d'informations, vous pouvez voir le document officiel .

class psycopg2.extras.Json(adapted, dumps=None)

    An ISQLQuote wrapper to adapt a Python object to json data type.

    Json can be used to wrap any object supported by the provided dumps function. If none is provided, the standard json.dumps() is used (simplejson for Python < 2.6; getquoted() will raise ImportError if the module is not available).

    dumps(obj)
    Serialize obj in JSON format.

    The default is to call json.dumps() or the dumps function provided in the constructor. You can override this method to create a customized JSON wrapper.
6
l mingzhi

Depuis les documents psycopg :

Remarque Vous pouvez utiliser register_adapter () pour adapter tout dictionnaire Python à JSON, en enregistrant Json ou toute sous-classe ou fabriquez un adaptateur compatible:

psycopg2.extensions.register_adapter(dict, psycopg2.extras.Json)

Ce paramètre est cependant global, il n'est donc pas compatible avec des adaptateurs similaires tels que celui enregistré par register_hstore (). Tout autre objet pris en charge par JSON peut être enregistré de la même manière, mais cela encombrera la règle d'adaptation par défaut, alors faites attention aux effets secondaires indésirables.

Donc, dans mon cas, ce que j'ai fait était:

from psycopg2.extensions import register_adapter

register_adapter(dict, Json)

Ça a marché comme sur des roulettes.

3
Felipe Augusto