Làm cách nào để truy xuất id đã chèn sau khi chèn hàng trong SQLite bằng Python?


176

Làm cách nào để truy xuất id đã chèn sau khi chèn hàng trong SQLite bằng Python? Tôi có bảng như thế này:

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

Tôi chèn một hàng mới với dữ liệu ví dụ username="test"password="test". Làm cách nào để truy xuất id được tạo theo cách an toàn trong giao dịch? Đây là một giải pháp trang web, trong đó hai người có thể chèn dữ liệu cùng một lúc. Tôi biết tôi có thể nhận được hàng đọc cuối cùng, nhưng tôi không nghĩ đó là giao dịch an toàn. Ai đó có thể cho tôi một lời khuyên?

Câu trả lời:


256

Bạn có thể sử dụng con trỏ.lastrowid (xem "Tiện ích mở rộng API DB tùy chọn"):

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

Nếu hai người đang chèn cùng một lúc, miễn là họ đang sử dụng các cursors khác nhau , cursor.lastrowidsẽ trả về idhàng cuối cùng cursorđược chèn:

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

Lưu ý rằng lastrowidtrả về Nonekhi bạn chèn nhiều hàng cùng một lúc với executemany:

cursor.executemany('INSERT INTO foo (username,password) VALUES (?,?)',
               (('baz','bar'),('bing','bop')))
print(cursor.lastrowid)
# None

16
+1 để giải thích rằng nó sẽ trả về id gần đây nhất bởi cá thể con trỏ riêng lẻ đó.
quakkels

43
Ngoài ra còn có last_insert_rowid()hàm SQL , cho phép bạn chèn id hàng cuối cùng dưới dạng khóa ngoại trong câu lệnh chèn tiếp theo , hoàn toàn bằng SQL.
Martijn Pieters

2
@MartijnPieters Bạn có thể đăng câu đó dưới dạng câu trả lời, mặc dù câu hỏi khá cũ. Nó vẫn có khả năng giúp người dùng đọc trang này.
Daniel Werner

3
xuất hiện sqlite3 Lastrowid của Python sử dụng last_insert_rowidbên dưới github.com/ghaering/pysqlite/blob/ mẹo (không đảm bảo chủ đề an toàn nhưng dường như là tùy chọn duy nhất FWIW). Xem thêm stackoverflow.com/q/2127138/32453
rogerdpack

2
Btw, điều này làm việc cho INSERTnhưng không làm việc cho UPDATE. Nhưng khi cập nhật một hàng, có lẽ bạn đã có id hàng tương ứng dù sao (tôi chỉ mất một lúc để tìm ra điều này ...).
CGFoX

4

Tất cả các khoản tín dụng cho @Martijn Pieters trong các bình luận:

Bạn có thể sử dụng chức năng last_insert_rowid():

Các last_insert_rowid()chức năng trả về ROWIDcủa chèn hàng cuối cùng từ các kết nối cơ sở dữ liệu mà gọi hàm. Hàm last_insert_rowid()SQL là một trình bao bọc xung quanh sqlite3_last_insert_rowid()chức năng giao diện C / C ++.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.