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

AP2*_*257 83 python postgresql psycopg2

我正在使用Python和psycopg2来连接到postgres.

当我插入一行...

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

...如何获取我刚刚插入的行的ID?试:

hundred = cursor.fetchall() 
Run Code Online (Sandbox Code Playgroud)

使用时返回错误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)
Run Code Online (Sandbox Code Playgroud)

简单地回来None.

更新:也是如此currval(即使将此命令直接用于postgres工作):

sql_string = "SELECT currval(pg_get_serial_sequence('hundred', 'id'));"
hundred_id = cursor.execute(sql_string)
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议吗?

谢谢!

Thi*_*ter 172

cursor.execute("INSERT INTO .... RETURNING id")
id_of_new_row = cursor.fetchone()[0]
Run Code Online (Sandbox Code Playgroud)

请不要手动构建包含值的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]
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅psycopg文档:http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries

  • 为了澄清,`RETURNING id`中的`id`应该是serial/primary key字段的字段名. (8认同)
  • 光标fetchone给了我"没有结果可以获取". (6认同)
  • 这是基于您使用常规游标的假设。如果您使用 dict 光标,则应调整代码:`id = curve.fetchone()["id"]` (4认同)
  • @AlisonS @Leonid我有同样的错误,但是在“ INSERT”查询的末尾添加“ RETURNING id”对我来说已经解决了。 (2认同)

Jam*_*own 11

我最终在这里是因为我有类似的问题,但我们使用的是Postgres-XC,它还不支持RETURNING ID子句.在这种情况下,您可以使用:

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

以防它对任何人都有用!

  • 请记住-如果在您之后但在lastval()命令返回序列的当前值之前,有人在数据库中插入一行,则在这样的两个语句中这样做会带来(非常小的)竞争条件风险。 (2认同)

Pau*_*ulo 5

对我来说,盗贼大师的答案和杰米·布朗的答案都不起作用。对我有用的是两者的结合,我想在这里回答,以便它可以帮助其他人。

我需要做的是:

cursor.execute('SELECT LASTVAL()')
id_of_new_row = cursor.fetchone()[0]
Run Code Online (Sandbox Code Playgroud)

即使在之后,该声明lastid = cursor.fetchone()['lastval']对我也不起作用cursor.execute('SELECT LASTVAL()')。仅此声明id_of_new_row = cursor.fetchone()[0]也不起作用。

也许我错过了一些东西。