【问题标题】:Adding dict object to postgresql将dict对象添加到postgresql
【发布时间】:2017-07-17 17:51:54
【问题描述】:

所以我在 Python3.5 上使用 psycopg2 将一些数据插入到 postgresql 数据库中。我想做的是有两列是字符串,最后一列只是一个 dict 对象。我不需要搜索字典,只需将其从数据库中拉出并使用即可。

例如:

uuid = "testName"
otherString = ""
dict = {'id':'122','name':'test','number':'444-444-4444'}

# add code here to store two strings and dict to postgresql

cur.execute('''SELECT dict FROM table where uuid = %s''', 'testName')
newDict = cur.fetchone()
print(newDict['number'])

这可能吗?如果可以,我会怎么做?

【问题讨论】:

    标签: python postgresql dictionary psycopg2


    【解决方案1】:

    如果您的 PostgreSQL 版本足够新 (9.4+) 并且 psycopg 版本 >= 2.5.4 所有键都是字符串并且值可以表示为 JSON,最好将其存储到 JSONB 列中。然后,如果需要,该列也可以搜索。只需将表创建为

    CREATE TABLE thetable (
        uuid TEXT,
        dict JSONB
    );
    

    (...并根据需要自然添加索引、主键等...) 将字典发送到 PostgreSQL 时,您只需要用 Json 适配器包装它;当从 PostgreSQL 接收 JSONB 值时会自动转换成字典,因此插入会变成

    from psycopg2.extras import Json, DictCursor
    
    cur = conn.cursor(cursor_factory=DictCursor)
    
    cur.execute('INSERT into thetable (uuid, dict) values (%s, %s)',
        ['testName', Json({'id':'122','name':'test','number':'444-444-4444'})])
    

    选择就像

    cur.execute('SELECT dict FROM thetable where uuid = %s', ['testName'])
    row = cur.fetchone()
    print(row['dict']) # its now a dictionary object with all the keys restored
    print(row['dict']['number']) # the value of the number key
    

    使用 JSONB,PostgreSQL 可以更有效地存储值,而不仅仅是将字典转储为文本。此外,可以对数据进行查询,例如只需从 JSONB 列中选择一些字段:

    >>> cur.execute("SELECT dict->>'id', dict->>'number' FROM thetable")
    >>> cur.fetchone()
    ['122', '444-444-4444']
    

    或者如果需要,您可以在查询中使用它们:

    >>> cur.execute("SELECT uuid FROM thetable WHERE dict->>'number' = %s',
        ['444-444-4444'])
    >>> cur.fetchall()
    [['testName', {'id': '122', 'name': 'test', 'number': '444-444-4444'}]]
    

    【讨论】:

    • 那么如果我需要返回整个字典对象,我可以用 return row['dict'] 来做到这一点?
    • @sbeyeler 可以使用与json.dumps 一起使用的任何数据结构。
    【解决方案2】:

    您可以在存储数据之前使用 JSON 序列化数据:

    import json
    
    data = json.dumps({'id':'122','name':'test','number':'444-444-4444'})
    

    然后在检索代码时反序列化它:

    cur.execute('SELECT dict from ....')
    res = cur.fetchone()
    
    dict = json.loads(res['dict'])
    print(dict['number'])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 2021-12-30
      • 1970-01-01
      • 2017-04-30
      • 2020-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多