Python/postgres/psycopg2: 获取刚插入的行 ID

我在用 Python 和 Psycopg2连接 postgres。

当我插入一行..。

sql_string = "INSERT INTO hundred (name,name_slug,status) VALUES ("
sql_string += hundred_name + ", '" + hundred_slug + "', " + status + ");"
cursor.execute(sql_string)

... 如何得到刚才插入的行的 ID? 尝试:

hundred = cursor.fetchall()

返回一个错误,同时使用 RETURNING id:

sql_string = "INSERT INTO domes_hundred (name,name_slug,status) VALUES ("
sql_string += hundred_name + ", '" + hundred_slug + "', " + status + ") RETURNING id;"
hundred = cursor.execute(sql_string)

只返回 None

更新: currval也是如此(即使在 postgres 中直接使用这个命令也可以) :

sql_string = "SELECT currval(pg_get_serial_sequence('hundred', 'id'));"
hundred_id = cursor.execute(sql_string)

有人能给点建议吗?

谢谢!

82583 次浏览
cursor.execute("INSERT INTO .... RETURNING id")
id_of_new_row = cursor.fetchone()[0]

并且请不要手动构建包含值的 SQL 字符串。你可以(也应该)分别传递值,这样就不需要转义和 SQL 注入:

sql_string = "INSERT INTO domes_hundred (name,name_slug,status) VALUES (%s,%s,%s) RETURNING id;"
cursor.execute(sql_string, (hundred_name, hundred_slug, status))
hundred = cursor.fetchone()[0]

更多细节请参阅心理警察文档: http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries

我之所以来到这里,是因为我遇到了类似的问题,但是我们使用的是 Postgres-XC,它还不支持 RETURING ID 子句。在这种情况下,您可以使用:

cursor.execute('INSERT INTO ........')
cursor.execute('SELECT LASTVAL()')
lastid = cursor.fetchone()['lastval']

以防它对任何人都有用!

对我来说,小偷大师的回答和杰米 · 布朗的都不管用。对我有效的是两者的结合,我想在这里回答,这样可以帮助其他人。

我需要做的是:

cursor.execute('SELECT LASTVAL()')
id_of_new_row = cursor.fetchone()[0]

语句 lastid = cursor.fetchone()['lastval']对我不起作用,甚至在 cursor.execute('SELECT LASTVAL()')之后也不起作用。单独的语句 id_of_new_row = cursor.fetchone()[0]也不起作用。

也许我遗漏了什么。

ThiefMaster 的方法对我很有用,对于 INSERTUPDATE命令都是如此。

如果在执行 INSERT/UPDATE命令之后对游标调用 cursor.fetchone(),但是没有返回值(RETURNING子句) ,则会引发异常: ProgrammingError('no results to fetch'))



insert_query = """
INSERT INTO hundred (id, name, name_slug, status)
VALUES (DEFAULT, %(name)s, %(name_slug)s, %(status)s)
RETURNING id;
"""


insert_query_values = {
"name": "",
"name_slug": "",
"status": ""
}


connection = psycopg2.connect(host="", port="", dbname="", user="", password="")


try:
with connection:
with connection.cursor() as cursor:
cursor.execute(insert_query, insert_query_values)
num_of_rows_affected = cursor.rowcount
new_row_id = cursor.fetchone()


except psycopg2.ProgrammingError as ex:
print("...", ex)
raise ex


finally:
connection.commit()
connection.close()