Як отримати вставлений ідентифікатор після вставки рядка в SQLite за допомогою Python?


176

Як отримати вставлений ідентифікатор після вставки рядка в SQLite за допомогою Python? У мене такий столик:

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

Я вставляю новий рядок із прикладом даних username="test"та password="test". Як отримати згенерований ідентифікатор безпечним чином для транзакцій? Це рішення для веб-сайтів, де двоє людей можуть одночасно вставляти дані. Я знаю, що можу отримати останній прочитаний рядок, але не думаю, що це безпечно для транзакцій. Може хтось дасть мені поради?

Відповіді:


256

Ви можете використовувати cursor.lastrowid (див. "Необов’язкові розширення API DB"):

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

Якщо дві людини вставляють одночасно, доки вони використовують різні cursors, cursor.lastrowidповернеться idдля останнього рядка, який було cursorвставлено:

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повертається, Noneколи ви вставляєте кілька рядків одночасно із executemany:

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

16
+1 для пояснення того, що він поверне останній ідентифікатор цього окремого екземпляра курсору.
землетруси

43
Існує також last_insert_rowid()функція SQL , що дозволяє вставляти ідентифікатор останнього рядка як зовнішній ключ у наступний оператор вставки, повністю в SQL.
Martijn Pieters

2
@MartijnPieters Ви можете опублікувати це як відповідь, хоча питання є досить старим. Це все ще може допомогти користувачам читати цю сторінку.
Даніель Вернер

3
З'являється, Lastrowid Pylitera sqlite3 використовує last_insert_rowidпід github.com/ghaering/pysqlite/blob/… (що не гарантується безпечним потоком, але здається єдиним варіантом FWIW). Дивіться також stackoverflow.com/q/2127138/32453
rogerdpack

2
До речі, це працює, INSERTале не працює UPDATE. Але коли ви оновлюєте рядок, ви, мабуть, вже маєте відповідний ідентифікатор рядка (просто мені знадобилося деякий час, щоб зрозуміти це ...).
CGFoX

4

Усі кредити до @Martijn Pieters у коментарях:

Ви можете використовувати функцію last_insert_rowid():

last_insert_rowid()Функція повертає ROWIDостанній рядок вставки з з'єднання з базою даних , яка викликається функція. Функція last_insert_rowid()SQL являє собою обгортку навколо sqlite3_last_insert_rowid()функції інтерфейсу C / C ++.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.