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

176 投票
5 回答
101140 浏览
提问于 2025-04-16 13:21

我正在使用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)

有没有人能给点建议?

谢谢!

5 个回答

7

考虑一下RETURNING子句,具体内容可以查看这个链接:http://www.postgresql.org/docs/8.3/static/sql-insert.html

18

我来到这里是因为我遇到了类似的问题,不过我们使用的是Postgres-XC,这个还不支持RETURNING ID这个功能。在这种情况下,你可以使用:

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

希望这对某些人有帮助!

322
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]

想了解更多细节,可以查看psycopg的文档:http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries

撰写回答