SqlAlchemy:获取插入的最后一条记录的id

时间:2011-12-21 12:14:50

标签: python postgresql sqlalchemy psycopg2

我在没有ORM的情况下使用SQLAlchemy,即使用手工制作的SQL状态来直接与后端数据库进行交互。在这种情况下,我使用PG作为我的后端数据库(psycopg2作为数据库驱动程序) - 我不知道这是否会影响答案。

我有这样的陈述(为简洁起见,假设conn是与db的有效连接):

conn.execute("INSERT INTO user (name, country_id) VALUES ('Homer', 123)")

还假设用户表由列组成(id [SERIAL PRIMARY KEY],name,country_id)

我如何获取新用户的ID(理想情况下,不再次访问数据库?)

7 个答案:

答案 0 :(得分:18)

您可以像INSERT statement这样使用RETURNING条款:

result = conn.execute("INSERT INTO user (name, country_id) VALUES ('Homer', 123)
                       RETURNING *")

如果您只想要结果id

rslt_id = conn.execute("INSERT INTO user (name, country_id) VALUES ('Homer', 123)
                        RETURNING id")

答案 1 :(得分:15)

用户lastrowid

result = conn.execute("INSERT INTO user (name, country_id) VALUES ('Homer', 123)")
result.lastrowid

答案 2 :(得分:4)

Python + SQLAlchemy

提交后,您将在对象中更新primary_key列ID(自动递增)。

db.session.add(new_usr)
db.session.commit() #will insert the new_usr data into database AND retrieve id
idd = new_usr.usrID # usrID is the autoincremented primary_key column. 
return jsonify(idd),201 #usrID = 12, correct id from table User in Database.

答案 3 :(得分:2)

当前SQLAlchemy documentation建议

result.inserted_primary_key应该有效!

答案 4 :(得分:1)

这个问题在stackoverflow上已经问了很多遍了,我没有看到完整的答案。谷歌搜索“ sqlalchemy插入获取新行的ID”会显示很多内容。

SQLAlchemy分为三个级别。 上图:ORM。 中:带有表类的数据库抽象(DBA)等。 底部:使用文本函数的SQL。

对于OO程序员来说,ORM级别看起来很自然,但是对于数据库程序员来说,它看上去很丑,并且ORM成为障碍。 DBA层是可以妥协的。对于数据库程序员来说,SQL层看起来很自然,而对于仅面向对象的程序员来说,SQL层看起来却很陌生。

每个级别都有自己的语法,类似但又不同,足以令人沮丧。除此之外,在线文档太多,很难找到答案。

我将描述如何在我使用的RDBMS的SQL层上获取插入的ID。

Table: User(user_id integer primary autoincrement key, user_name string)
conn: Is a Connection obtained within SQLAlchemy to the DBMS you are using.


SQLite
======
insstmt = text(
    '''INSERT INTO user (user_name)
    VALUES (:usernm) ''' )
# Execute within a transaction (optional)
txn = conn.begin()
result = conn.execute(insstmt, usernm='Jane Doe')
# The id!
recid = result.lastrowid
txn.commit()


MS SQL Server
=============
insstmt = text(
    '''INSERT INTO user (user_name) 
    OUTPUT inserted.record_id
    VALUES (:usernm) ''' )
txn = conn.begin()
result = conn.execute(insstmt, usernm='Jane Doe')
# The id!
recid = result.fetchone()[0]
txn.commit()


MariaDB/MySQL
=============
insstmt = text(
    '''INSERT INTO user (user_name)
    VALUES (:usernm) ''' )
txn = conn.begin()
result = conn.execute(insstmt, usernm='Jane Doe')
# The id!
recid = conn.execute(text('SELECT LAST_INSERT_ID()')).fetchone()[0]
txn.commit()


Postgres
========
insstmt = text(
    '''INSERT INTO user (user_name)
    VALUES (:usernm) 
    RETURNING user_id ''' )
txn = conn.begin()
result = conn.execute(insstmt, usernm='Jane Doe')
# The id!
recid = result.fetchone()[0]
txn.commit()

答案 5 :(得分:0)

result.inserted_primary_key

为我工作。唯一要注意的是,这将返回一个包含last_insert_id的列表。

答案 6 :(得分:0)

确保使用fetchrow/fetch来接收returning对象

insert_stmt = user.insert().values(name="homer", country_id="123").returning(user.c.id)

row_id = await conn.fetchrow(insert_stmt)