Comment récupérer l'ID inséré après avoir inséré une ligne dans SQLite en utilisant Python?

176

Comment récupérer l'ID inséré après avoir inséré une ligne dans SQLite en utilisant Python? J'ai une table comme celle-ci:

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

J'insère une nouvelle ligne avec des exemples de données username="test"et password="test". Comment récupérer l'identifiant généré de manière sécurisée par transaction? Il s'agit d'une solution de site Web, où deux personnes peuvent insérer des données en même temps. Je sais que je peux obtenir la dernière ligne lue, mais je ne pense pas que ce soit une transaction sûre. Quelqu'un peut-il me donner des conseils?

Jeanne
la source

Réponses:

256

Vous pouvez utiliser cursor.lastrowid (voir "Extensions d'API DB facultatives"):

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

Si deux personnes insèrent en même temps, tant qu'elles utilisent des cursors différents , cursor.lastrowidrenverra le idpour la dernière ligne cursorinsérée:

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

Notez que lastrowidretourne Nonelorsque vous insérez plus d'une ligne à la fois avec executemany:

cursor.executemany('INSERT INTO foo (username,password) VALUES (?,?)',
               (('baz','bar'),('bing','bop')))
print(cursor.lastrowid)
# None
unutbu
la source
16
+1 pour expliquer qu'il renverra l'identifiant le plus récent de cette instance de curseur individuelle.
quakkels
43
Il existe également la last_insert_rowid()fonction SQL , vous permettant d'insérer l'ID de la dernière ligne comme clé étrangère dans une instruction d'insertion suivante , entièrement en SQL.
Martijn Pieters
2
@MartijnPieters Vous pouvez poster cela comme réponse, même si la question est assez ancienne. Cela aiderait encore potentiellement les utilisateurs à lire cette page.
Daniel Werner
3
apparaît l'utilisation de sqlite3 lastrowid de Python en last_insert_rowiddessous github.com/ghaering/pysqlite/blob / ... (ce qui n'est pas garanti threadsafe mais semble la seule option FWIW). Voir aussi stackoverflow.com/q/2127138/32453
rogerdpack
2
Btw, cela fonctionne pour INSERTmais ne fonctionne pas pour UPDATE. Mais lors de la mise à jour d'une ligne, vous avez probablement déjà l'ID de ligne correspondant de toute façon (il m'a juste fallu un certain temps pour comprendre cela ...).
CGFoX
4

Tous les crédits à @Martijn Pieters dans les commentaires:

Vous pouvez utiliser la fonction last_insert_rowid():

le last_insert_rowid() fonction renvoie l' ROWIDinsertion de la dernière ligne à partir de la connexion à la base de données qui a appelé la fonction. La last_insert_rowid()fonction SQL est un wrapper autour de la sqlite3_last_insert_rowid()fonction d'interface C / C ++.

Stefan van den Akker
la source