使用Python在SQLite中插入行后如何检索插入的ID?


175

使用Python在SQLite中插入行后如何检索插入的ID?我有这样的表:

id INT AUTOINCREMENT PRIMARY KEY,
username VARCHAR(50),
password VARCHAR(50)

我用示例数据username="test"和插入新行password="test"。如何以交易安全的方式检索生成的ID?这是针对网站解决方案的,其中两个人可能同时插入数据。我知道我可以读到最后一行,但是我认为这不是事务安全的。有人可以给我一些建议吗?

Answers:


255

您可以使用cursor.lastrowid(请参阅“可选的DB API扩展”):

connection=sqlite3.connect(':memory:')
cursor=connection.cursor()
cursor.execute('''CREATE TABLE foo (id integer primary key autoincrement ,
                                    username varchar(50),
                                    password varchar(50))''')
cursor.execute('INSERT INTO foo (username,password) VALUES (?,?)',
               ('test','test'))
print(cursor.lastrowid)
# 1

如果两个人同时插入,只要他们使用不同cursor的,cursor.lastrowid就会idcursor插入的最后一行返回:

cursor.execute('INSERT INTO foo (username,password) VALUES (?,?)',
               ('blah','blah'))

cursor2=connection.cursor()
cursor2.execute('INSERT INTO foo (username,password) VALUES (?,?)',
               ('blah','blah'))

print(cursor2.lastrowid)        
# 3
print(cursor.lastrowid)
# 2

cursor.execute('INSERT INTO foo (id,username,password) VALUES (?,?,?)',
               (100,'blah','blah'))
print(cursor.lastrowid)
# 100

请注意,使用一次插入多个行时会lastrowid返回:Noneexecutemany

cursor.executemany('INSERT INTO foo (username,password) VALUES (?,?)',
               (('baz','bar'),('bing','bop')))
print(cursor.lastrowid)
# None

16
+1,用于解释它将返回该单个游标实例的最新ID。
quakkels

43
还有一个last_insert_rowid()SQL函数,允许您完全在SQL 中将一个行ID作为外键插入到下一个 insert语句中。
马丁·彼得

2
@MartijnPieters即使问题很老,也可以将其发布为答案。它仍然可能帮助用户阅读此页面。
Daniel Werner

3
出现last_insert_rowidgithub.com/ghaering/pysqlite/blob/…下面的是Python的sqlite3 lastrowid (它不能保证线程安全,但似乎是FWIW的唯一选择)。另请参阅stackoverflow.com/q/2127138/32453
rogerdpack

2
顺便说一句,这适用于,INSERT但不适用于UPDATE。但是,当更新一行时,您可能已经已经有了相应的行ID(只是花了我一段时间才能弄清楚……)。
CGFoX
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.