Come recuperare l'id inserito dopo aver inserito la riga in SQLite usando Python?


176

Come recuperare l'id inserito dopo aver inserito la riga in SQLite usando Python? Ho un tavolo come questo:

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

Inserisco una nuova riga con dati di esempio username="test"e password="test". Come recuperare l'ID generato in modo sicuro per la transazione? Questo è per una soluzione di sito Web, in cui due persone possono inserire dati contemporaneamente. So di poter ottenere l'ultima riga di lettura, ma non penso che sia sicuro per le transazioni. Qualcuno può darmi qualche consiglio?

Risposte:


256

È possibile utilizzare cursor.lastrowid (consultare "Estensioni API DB opzionali"):

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

Se due persone inseriscono contemporaneamente, purché utilizzino cursors diverse , cursor.lastrowidverrà restituito il valore idper l'ultima riga cursorinserita:

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

Nota che lastrowidritorna Nonequando inserisci più di una riga alla volta con executemany:

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

16
+1 per spiegare che restituirà l'id più recente di quella singola istanza del cursore.
quakkels il

43
Esiste anche la last_insert_rowid()funzione SQL , che consente di inserire l'id dell'ultima riga come chiave esterna in un'istruzione insert successiva , interamente in SQL.
Martijn Pieters

2
@MartijnPieters Potresti postarlo come risposta, anche se la domanda è piuttosto vecchia. Aiuterebbe potenzialmente gli utenti a leggere questa pagina.
Daniel Werner,

3
appare sqlite3 di Python lastrowid utilizza last_insert_rowidsotto github.com/ghaering/pysqlite/blob/… (che non è garantito thread-safe ma sembra l'unica opzione FWIW). Vedi anche stackoverflow.com/q/2127138/32453
rogerdpack

2
A proposito, questo funziona per INSERTma non funziona per UPDATE. Ma quando aggiorni una riga, probabilmente hai già l'ID riga corrispondente comunque (mi ci è voluto un po 'di tempo per capirlo ...).
CGFoX,

4

Tutti i crediti a @Martijn Pieters nei commenti:

Puoi usare la funzione last_insert_rowid():

La last_insert_rowid()funzione restituisce l' ROWIDinserimento dell'ultima riga dalla connessione al database che ha invocato la funzione. La last_insert_rowid()funzione SQL è un wrapper per la sqlite3_last_insert_rowid()funzione di interfaccia C / C ++.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.