208 votes

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

Comment récupérer l'identifiant 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 données d'exemple username="test" y password="test" . Comment puis-je récupérer l'identifiant généré d'une manière sûre pour les transactions ? Il s'agit d'une solution pour un 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 cela soit sûr pour les transactions. Quelqu'un peut-il me donner des conseils ?

301voto

unutbu Points 222216

Vous pourriez utiliser curseur.lastrowid (voir "Extensions facultatives de l'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

Si deux personnes procèdent à l'insertion en même temps, tant qu'elles utilisent des cartes différentes, il est possible d'obtenir des résultats différents. cursor s, cursor.lastrowid retournera le id pour la dernière ligne que cursor inséré :

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 lastrowid renvoie à None lorsque 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

20 votes

+1 pour avoir expliqué qu'il retournera l'identifiant le plus récent pour cette instance de curseur individuelle.

48 votes

Il y a aussi le last_insert_rowid() Fonction SQL permettant d'insérer la dernière ligne d'identification comme clé étrangère dans un fichier suivant déclaration d'insertion, entièrement en SQL.

3 votes

@MartijnPieters Vous pourriez poster cela comme réponse, même si la question est assez ancienne. Cela pourrait quand même aider les utilisateurs qui lisent cette page.

20voto

Neftas Points 1026

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

Vous pouvez utiliser la fonction last_insert_rowid() :

El last_insert_rowid() renvoie la fonction ROWID de la dernière insertion de ligne à partir de la connexion à la base de données qui a invoqué la fonction. Le site last_insert_rowid() La fonction SQL est une enveloppe autour de la fonction sqlite3_last_insert_rowid() Fonction d'interface C/C++.

Mise à jour : vous pouvez utiliser RETURNING en SQLite 3.35 :

create table users (
  id integer primary key,
  first_name text,
  last_name text
);

insert into users (first_name, last_name)
values ('Jane', 'Doe')
returning id;

3 votes

Le site LAST_INSERT_ROWID() est spécifique à SQLite. Le site cursor.lastrowid fait partie de la spécification de l'interface DB-API de Python, elle devrait donc être plus portable.

0 votes

Notez que le RETURNING La clause fonctionne avec cursor.execute mais ne fonctionnera pas avec cursor.executemany . Python se plaindra que "executemany() ne peut exécuter que des instructions DML".

1 votes

En fonction de votre programme, vous devez également faire attention aux conditions de course, si plusieurs threads peuvent écrire dans la base de données en parallèle. Dans ce cas, vous ne pouvez pas supposer que last_insert_rowid correspond à la ligne que vous venez d'insérer. Heureusement, RETURNING peut maintenant être utilisé pour résoudre ce problème, bien qu'il ne soit pas encore disponible partout.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X