Como recuperar o ID inserido após inserir linha no SQLite usando Python?

176

Como recuperar o ID inserido após inserir linha no SQLite usando Python? Eu tenho tabela como esta:

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

Eu insiro uma nova linha com dados de exemplo username="test"e password="test". Como recupero o ID gerado de uma maneira segura para transações? Isso é para uma solução de site, na qual duas pessoas podem inserir dados ao mesmo tempo. Sei que posso obter a última linha de leitura, mas não acho que isso seja seguro para transações. Alguém pode me dar um conselho?

Jane
fonte

Respostas:

256

Você pode usar o cursor.lastrowid (consulte "Extensões opcionais da API do banco de dados"):

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 duas pessoas estiverem inserindo ao mesmo tempo, desde que estejam usando cursors diferentes , cursor.lastrowidretornará o idpara a última linha que foi cursorinserida:

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

Observe que lastrowidretorna Nonequando você insere mais de uma linha por vez com executemany:

cursor.executemany('INSERT INTO foo (username,password) VALUES (?,?)',
               (('baz','bar'),('bing','bop')))
print(cursor.lastrowid)
# None
unutbu
fonte
16
+1 por explicar que ele retornará o ID mais recente por essa instância individual do cursor.
quakkels
43
Há também a last_insert_rowid()função SQL , permitindo inserir o último ID da linha como uma chave estrangeira em uma próxima instrução de inserção, inteiramente no SQL.
Martijn Pieters
2
@MartijnPieters Você pode postar isso como resposta, mesmo que a pergunta seja bastante antiga. Ainda assim, potencialmente ajudaria os usuários a ler esta página.
Daniel Werner
3
aparece usos lastrowid sqlite3 do Python last_insert_rowiddebaixo github.com/ghaering/pysqlite/blob/... (que não é garantido threadsafe, mas parece ser a única opção FWIW). Veja também stackoverflow.com/q/2127138/32453
rogerdpack
2
Btw, isso funciona para, INSERTmas não funciona UPDATE. Mas, ao atualizar uma linha, você provavelmente já tem o ID da linha correspondente de qualquer maneira (demorei um pouco para descobrir isso ...).
CGFoX 25/10
4

Todos os créditos a @Martijn Pieters nos comentários:

Você pode usar a função last_insert_rowid():

A last_insert_rowid()função retorna a ROWIDinserção da última linha da conexão com o banco de dados que chamou a função. A last_insert_rowid()função SQL é um invólucro em torno da sqlite3_last_insert_rowid()função de interface C / C ++.

Stefan van den Akker
fonte