¿Cómo recuperar la identificación insertada después de insertar una fila en SQLite usando Python?

176

¿Cómo recuperar la identificación insertada después de insertar una fila en SQLite usando Python? Tengo una mesa como esta:

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

Inserto una nueva fila con datos de ejemplo username="test"y password="test". ¿Cómo recupero la identificación generada de una manera segura para la transacción? Esto es para una solución de sitio web, donde dos personas pueden estar insertando datos al mismo tiempo. Sé que puedo obtener la última fila de lectura, pero no creo que sea una transacción segura. ¿Alguien puede darme algún consejo?

Jane
fuente

Respuestas:

256

Puede usar cursor.lastrowid (consulte "Extensiones opcionales de 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 dos personas están insertando al mismo tiempo, siempre y cuando estén usando diferentes cursorcorreos electrónicos, cursor.lastrowiddevolverá idla última fila que se cursorinsertó:

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

Tenga en cuenta que se lastrowiddevuelve Nonecuando inserta más de una fila a la vez con executemany:

cursor.executemany('INSERT INTO foo (username,password) VALUES (?,?)',
               (('baz','bar'),('bing','bop')))
print(cursor.lastrowid)
# None
unutbu
fuente
16
+1 para explicar que devolverá la identificación más reciente de esa instancia de cursor individual.
quakkels
43
También existe la last_insert_rowid()función SQL , que le permite insertar la última identificación de fila como una clave foránea en una siguiente instrucción de inserción, completamente en SQL.
Martijn Pieters
2
@MartijnPieters Puede publicar eso como respuesta, a pesar de que la pregunta es bastante antigua. Aún podría ayudar a los usuarios a leer esta página.
Daniel Werner
3
aparece sqlite3 lastrowid de Python utiliza last_insert_rowiddebajo de github.com/ghaering/pysqlite/blob/… (que no está garantizado para subprocesos pero parece la única opción FWIW). Ver también stackoverflow.com/q/2127138/32453
rogerdpack
2
Por cierto, esto funciona INSERTpero no funciona UPDATE. Pero al actualizar una fila, probablemente ya tenga la identificación de fila correspondiente de todos modos (solo me tomó un tiempo descubrir esto ...).
CGFoX
4

Todos los créditos a @Martijn Pieters en los comentarios:

Puedes usar la función last_insert_rowid():

La last_insert_rowid()función devuelve la ROWIDinserción de la última fila de la conexión de la base de datos que invocó la función. La last_insert_rowid()función SQL es un contenedor alrededor de la sqlite3_last_insert_rowid()función de interfaz C / C ++.

Stefan van den Akker
fuente