当前位置:  开发笔记 > 编程语言 > 正文

无法使用Python在PostgreSQL中获取最后一个插入的id

如何解决《无法使用Python在PostgreSQL中获取最后一个插入的id》经验,为你挑选了1个好方法。

我有一个表格,test_table其中一个字段id会自动递增.现在我想要的是在运行INSERT语句后立即获取最后一个插入的id .此时我所有的尝试都会导致None(顺便说一句,我在MySQL中得到了相同的行为,只有在SQLite中一切正常).这是一些重现这种意外行为的代码:

>>> import psycopg2
>>> cnx = psycopg2.connect(host="127.0.0.1", dbname="reestr", user="postgres", password="postgres")
>>> cur = cnx.cursor()
>>> cur.execute("INSERT INTO test_table (field_1) VALUES ('hello')")
>>> cur.execute("INSERT INTO test_table (field_1) VALUES ('hello')")
>>> cur.execute("SELECT CURRVAL(pg_get_serial_sequence('test_table','id'))")
>>> res = cur.fetchone()
>>> res
(None,)
>>> cur.execute("SELECT id, field_1 FROM test_table")
>>> res = cur.fetchall()
>>> res
[(1, 'hello'), (2, 'hello')]

我们清楚地看到,该id列自动增量,但由于一些疯狂的原因,SELECT CURRVAL(pg_get_serial_sequence('test_table','id'))没有返回任何东西.这有什么问题?顺便说一下,我还尝试在一个事务中显式运行这些查询,并得到完全相同的结果.



1> Serge Balles..:

因为PostgreSQL文档说:

pg_get_serial_sequence(table_name,column_name)| 文字| 获取serial或bigserial列使用的序列的名称

(强调我的)因为你的专栏没有明确宣布为SERIAL或BIGSERIAL,所以pg_get_serial_sequence什么都不返回.如果您想使用pg_get_serial_sequence,您必须声明:

CREATE TABLE test_table (id SERIAL, field_1 VARCHAR(128))

无论如何,生成的密钥是PostgreSQL中的常见问题.我在Java中遇到过它,但它在Python中应该是相同的.

PostgreSQL具有特定的扩展名,而不是从游标中访问最后生成的密钥的常用习惯用法RETURNING.从INSERT的 PostreSQL文档中提取

[ WITH [ RECURSIVE ] with_query [, ...] ]
INSERT INTO table [ ( column [, ...] ) ]
    { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

...可选的RETURNING子句使INSERT根据实际插入的每一行计算和返回值.这主要用于获取默认提供的值,例如序列号... RETURNING列表的语法与SELECT的输出列表的语法相同.

所以我的建议是坚持你当前的声明,但是将你的插入代码更改为:

>>> cur.execute("INSERT INTO test_table (field_1) VALUES ('hello') RETURNING id")
>>> res = cur.fetchone()
>>> last_inserted_id = res[0]

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有