Psycopg2在postgres数据库中插入python字典

时间:2016-08-29 09:39:54

标签: postgresql python-3.x dictionary psycopg2

在python 3+中,我想将字典(或pandas数据帧)中的值插入数据库。我选择了带有postgres数据库的psycopg2。

问题是我无法弄清楚这样做的正确方法。我可以轻松地连接要执行的SQL字符串,但psycopg2文档明确警告不要这样做。理想情况下我想做这样的事情:

cur.execute("INSERT INTO table VALUES (%s);", dict_data)

并希望执行可以确定dict的键与表中的列匹配。这没用。从psycopg2文档的例子我得到了这种方法

cur.execute("INSERT INTO table (" + ", ".join(dict_data.keys()) + ") VALUES (" + ", ".join(["%s" for pair in dict_data]) + ");", dict_data)

我从中得到了

TypeError: 'dict' object does not support indexing

将字典插入到具有匹配列名的表中的最佳植物方式是什么?

5 个答案:

答案 0 :(得分:5)

两种解决方案:

d = {'k1': 'v1', 'k2': 'v2'}

insert = 'insert into table (%s) values %s'
l = [(c, v) for c, v in d.items()]
columns = ','.join([t[0] for t in l])
values = tuple([t[1] for t in l])
cursor = conn.cursor()
print cursor.mogrify(insert, ([AsIs(columns)] + [values]))

keys = d.keys()
columns = ','.join(keys)
values = ','.join(['%({})s'.format(k) for k in keys])
insert = 'insert into table ({0}) values ({1})'.format(columns, values)
print cursor.mogrify(insert, d)

输出:

insert into table (k2,k1) values ('v2', 'v1')
insert into table (k2,k1) values ('v2','v1')

答案 1 :(得分:1)

[建议的答案/解决方法 - 感谢更好的答案!]

经过一些试验/错误后,我得到以下工作:

sql = "INSERT INTO table (" + ", ".join(dict_data.keys()) + ") VALUES (" + ", ".join(["%("+k+")s" for k in dict_data]) + ");"

这给出了sql字符串

"INSERT INTO table (k1, k2, ... , kn) VALUES (%(k1)s, %(k2)s, ... , %(kn)s);"

可以由

执行
with psycopg2.connect(database='deepenergy') as con:
    with con.cursor() as cur:
        cur.execute(sql, dict_data)

发布/缺点?

答案 2 :(得分:0)

有时我会遇到这个问题,尤其是关于JSON数据的问题,我自然希望将其作为命令处理。非常相似。 。但是也许可读性更高?

#include <stdio.h>
#include <time.h>

#define BLOCKSIZE 256
#define META (6 + 9 + (3 * (sizeof (int))) + (3 * (sizeof(time_t))))


typedef struct Inode {
   char a;
   char b;
   char c[9];
   int d;
   char e;
   char f;
   int g;
   int h;
   time_t i;
   time_t j;
   time_t k;
   char l;
   char m[BLOCKSIZE - META];
} Inode;

我通常从迭代器内部调用这种类型的东西,通常包装在try / except中。游标(cur)已经在外部作用域中定义了,或者可以修改函数签名并在其中传递游标实例。我很少只插入一行。 。与其他解决方案一样,如果基础架构也允许,则允许缺少列数/值。只要在插入过程中未修改键视图下的dict,就不需要按名称指定键,因为值将按在键视图中的顺序进行排序。

答案 3 :(得分:0)

使用%(name)的占位符可以解决问题:

dict_data = {'key1':val1, 'key2':val2}

cur.execute("""INSERT INTO table (field1, field2) 
VALUES (%(key1)s, %(key2)s);""", 
dict_data)

您可以在psycopg2 doc Passing parameters to SQL queries

中找到用法

答案 4 :(得分:0)

这是另一种直接插入字典的解决方案

产品型号(具有以下数据库列)

name
description
price
image
digital - (defaults to False)
quantity
created_at - (defaults to current date)

解决方案

    data = {
        "name": "product_name",
        "description": "product_description",
        "price": 1,
        "image": "https",
        "quantity": 2,
    }
    cur = conn.cursor()
    cur.execute(
        "INSERT INTO products (name,description,price,image,quantity) "
        "VALUES(%(name)s, %(description)s, %(price)s, %(image)s, %(quantity)s)", data
    )

    conn.commit()
    conn.close()

注意:要插入的列在执行语句.. INTO products (column names to be filled) VALUES ..., data <- the dictionary (should be the same **ORDER** of keys)

中指定