postgresql 如何使用psycopg2.extras.execute_values()在一个表中插入多条记录,当其中一列是序列时?

lymnna71  于 2023-04-20  发布在  PostgreSQL
关注(0)|答案(1)|浏览(196)

我尝试使用psycopg2.extras.execute_values在单个数据库调用中插入多条记录(cursor,statement,argument_list)函数。当我有一个只有字符串或整数作为字段值的列表时,它可以工作。但是我希望id字段从postgres序列中分配。我尝试使用nextval('name_of_sequence)作为值,但它被视为字符串,因此对于我的id列无效,这是一个begint。

qni6mghb

qni6mghb1#

两种方法来处理这个问题。
1)这样做:
alter <the_table> alter column id set default nextval('name_of_sequence').
那么你就不必在查询中指定id值。如果序列专用于该表。列,那么还可以:
alter sequence name_of_sequence owned by <table_name>.id;
这将创建一个依赖项,以便如果删除表,序列也将被删除。
(2)
保持序列独立,只需使用以下步骤根据需要提取值。
SQL模式

create table py_seq_test(id bigint, fld_1 varchar);
create sequence py_seq;

Python代码
a)常规执行

import psycopg2

con = psycopg2.connect("dbname=test host=localhost  user=postgres")
cur = con.cursor()

cur.execute("insert into py_seq_test values(nextval('py_seq'), %s)", ['test1'])
cur.execute("insert into py_seq_test values(nextval('py_seq'), '%s')", ['test2'])
con.commit()
cur.execute("select * from py_seq_test")
cur.fetchall()

[(1, 'test'), (2, 'test2')]

B)执行值

from psycopg2.extras import execute_values

execute_values(cur, 
   "insert into py_seq_test values %s", 
   [('test3',), ('test4',) ], 
   template="(nextval('py_seq'),  %s)")

con.commit()

cur.execute("select * from py_seq_test")
cur.fetchall()

[(1, 'test'), (2, 'test2'), (3, 'test3'), (4, 'test4']

更新

execute()execute_values()在插入10000个值时的比较示例。这是在ipython中使用%%time单元格魔术完成的。

large_list = [(val,) for val in range(10000)]

%%time
for i_val in large_list:
    cur.execute("insert into py_seq_test values(nextval('py_seq'), %s)", [i_val[0]])
con.commit()

CPU times: user 157 ms, sys: 103 ms, total: 260 ms
Wall time: 790 ms

%%time
execute_values(cur, 
   "insert into py_seq_test values %s", 
   large_list, 
   template="(nextval('py_seq'),  %s)")
con.commit()

CPU times: user 30.6 ms, sys: 320 µs, total: 30.9 ms
Wall time: 164 ms

相关问题