Bagaimana cara mengambil id yang dimasukkan setelah memasukkan baris dalam SQLite menggunakan Python?

176

Bagaimana cara mengambil id yang dimasukkan setelah memasukkan baris dalam SQLite menggunakan Python? Saya punya tabel seperti ini:

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

Saya menyisipkan baris baru dengan data contoh username="test"dan password="test". Bagaimana cara mengambil id yang dihasilkan dengan cara transaksi yang aman? Ini untuk solusi situs web, di mana dua orang mungkin memasukkan data secara bersamaan. Saya tahu saya bisa mendapatkan baris membaca terakhir, tetapi saya tidak berpikir bahwa transaksi aman. Adakah yang bisa memberi saya nasihat?

Jane
sumber

Jawaban:

256

Anda dapat menggunakan cursor.lastrowid (lihat "Ekstensi API DB opsional"):

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

Jika dua orang memasukkan secara bersamaan, selama mereka menggunakan cursors yang berbeda , cursor.lastrowidakan mengembalikan iduntuk baris terakhir yang cursordisisipkan:

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

Perhatikan bahwa lastrowidkembali Noneketika Anda memasukkan lebih dari satu baris sekaligus dengan executemany:

cursor.executemany('INSERT INTO foo (username,password) VALUES (?,?)',
               (('baz','bar'),('bing','bop')))
print(cursor.lastrowid)
# None
unutbu
sumber
16
+1 untuk menjelaskan bahwa itu akan mengembalikan id terbaru oleh instance kursor individual itu.
quakkels
43
Ada juga last_insert_rowid()fungsi SQL , yang memungkinkan Anda untuk memasukkan id baris terakhir sebagai kunci asing dalam pernyataan masukkan berikutnya , seluruhnya dalam SQL.
Martijn Pieters
2
@ MartijnPieters Anda dapat memposting itu sebagai jawaban, meskipun pertanyaannya sudah cukup lama. Masih berpotensi membantu pengguna membaca halaman ini.
Daniel Werner
3
muncul Python's sqlite3 lastrowid menggunakan di last_insert_rowidbawah github.com/ghaering/pysqlite/blob/… (yang tidak dijamin threadsafe tetapi tampaknya satu-satunya pilihan FWIW). Lihat juga stackoverflow.com/q/2127138/32453
rogerdpack
2
Btw, ini bekerja untuk INSERTtetapi tidak bekerja untuk UPDATE. Tetapi ketika memperbarui baris, Anda mungkin sudah memiliki id baris yang sesuai (hanya butuh beberapa saat untuk mencari tahu ini ...).
CGFoX
4

Semua kredit ke @ Martijn Pieters di komentar:

Anda dapat menggunakan fungsi ini last_insert_rowid():

The last_insert_rowid()mengembalikan fungsi ROWIDyang terakhir insert baris dari koneksi database yang dipanggil fungsi. Fungsi last_insert_rowid()SQL adalah pembungkus di sekitar sqlite3_last_insert_rowid()fungsi antarmuka C / C ++.

Stefan van den Akker
sumber