我在没有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(理想情况下,不再次访问数据库?)
答案 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)
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)