在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
将字典插入到具有匹配列名的表中的最佳植物方式是什么?
答案 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)