Psycopg2 вставить словарь python как json

Я хочу вставить словарь python в качестве json в мою базу данных postgresql (через python и psycopg2). У меня есть:

...
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'))

...

И появляется сообщение об ошибке:

    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'))
psycopg2.ProgrammingError: can't adapt type 'dict'

Я не уверен, как исходить отсюда. Я не могу найти что-либо в Интернете о том, как это сделать, и я очень новичок в psycopg2.

Ответ 1

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'))

Это решит вашу проблему. Однако вы действительно должны хранить ключи и значения в своих отдельных столбцах. Чтобы получить словарь, выполните следующие действия:

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

Надеюсь, что это поможет.

Ответ 2

Вы можете использовать psycopg2.extras.Json чтобы конвертировать dict в json, который принимает postgre.

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)

Для получения дополнительной информации вы можете увидеть офисный документ.

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.

Ответ 3

Из документации psycopg:

Примечание. Вы можете использовать register_adapter() для адаптации любого словаря Python к JSON, регистрируя Json, любой подкласс или фабрику, создавая совместимый адаптер:

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

Однако этот параметр является глобальным, поэтому он не совместим с аналогичными адаптерами, например, зарегистрированными в register_hstore(). Любой другой объект, поддерживаемый JSON, может быть зарегистрирован таким же образом, но это приведет к нарушению правила адаптации по умолчанию, поэтому будьте осторожны с нежелательными побочными эффектами.

Итак, в моем случае я сделал следующее:

from psycopg2.extensions import register_adapter

register_adapter(dict, Json)

Оно работало завораживающе.