Wie kann ich die eingefügte ID nach dem Einfügen einer Zeile in SQLite mit Python abrufen?

176

Wie kann ich die eingefügte ID nach dem Einfügen einer Zeile in SQLite mit Python abrufen? Ich habe einen Tisch wie diesen:

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

Ich füge eine neue Zeile mit Beispieldaten username="test"und ein password="test". Wie rufe ich die generierte ID transaktionssicher ab? Dies ist eine Website-Lösung, bei der möglicherweise zwei Personen gleichzeitig Daten einfügen. Ich weiß, dass ich die letzte gelesene Zeile erhalten kann, aber ich denke nicht, dass dies transaktionssicher ist. Kann mir jemand einen Rat geben?

Jane
quelle

Antworten:

256

Sie können cursor.lastrowid verwenden (siehe "Optionale DB-API-Erweiterungen"):

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

Wenn zwei Personen gleichzeitig einfügen, solange sie unterschiedliche cursors verwenden, cursor.lastrowidwird das idfür die letzte cursoreingefügte Zeile zurückgegeben :

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

Beachten Sie, dass dies lastrowidzurückgegeben wird, Nonewenn Sie mehr als eine Zeile gleichzeitig einfügen mit executemany:

cursor.executemany('INSERT INTO foo (username,password) VALUES (?,?)',
               (('baz','bar'),('bing','bop')))
print(cursor.lastrowid)
# None
unutbu
quelle
16
+1 für die Erklärung, dass die neueste ID dieser einzelnen Cursorinstanz zurückgegeben wird.
Quakkels
43
Es gibt auch die last_insert_rowid()SQL-Funktion , mit der Sie die letzte Zeilen-ID als Fremdschlüssel in eine nächste Einfügeanweisung vollständig in SQL einfügen können.
Martijn Pieters
2
@MartijnPieters Sie könnten das als Antwort posten, obwohl die Frage ziemlich alt ist. Es würde Benutzern möglicherweise weiterhin beim Lesen dieser Seite helfen.
Daniel Werner
3
erscheint Pythons sqlite3 lastrowid verwendet last_insert_rowidunter github.com/ghaering/pysqlite/blob/… (was nicht threadsicher garantiert ist, aber die einzige Option FWIW zu sein scheint). Siehe auch stackoverflow.com/q/2127138/32453
rogerdpack
2
Übrigens funktioniert das für INSERT, aber nicht für UPDATE. Aber wenn Sie eine Zeile aktualisieren, haben Sie wahrscheinlich sowieso bereits die entsprechende Zeilen-ID (ich habe nur eine Weile gebraucht, um das herauszufinden ...).
CGFoX
4

Alle Credits an @Martijn Pieters in den Kommentaren:

Sie können die Funktion verwenden last_insert_rowid():

Die last_insert_rowid()Funktion gibt die ROWIDletzte Zeileneinfügung von der Datenbankverbindung zurück, die die Funktion aufgerufen hat. Die last_insert_rowid()SQL-Funktion ist ein Wrapper um die sqlite3_last_insert_rowid()C / C ++ - Schnittstellenfunktion.

Stefan van den Akker
quelle