Làm cách nào để tôi nhận được id id sau khi INSERT vào cơ sở dữ liệu MySQL bằng Python?


182

Tôi thực hiện một câu lệnh INSERT INTO

cursor.execute("INSERT INTO mytable(height) VALUES(%s)",(height))

và tôi muốn lấy khóa chính.

Bảng của tôi có 2 cột:

id      primary, auto increment
height  this is the other column.

Làm thế nào để tôi có được "id", sau khi tôi vừa chèn cái này?


Câu trả lời:


242

Sử dụng cursor.lastrowidđể lấy ID hàng cuối cùng được chèn vào đối tượng con trỏ hoặc connection.insert_id()để lấy ID từ lần chèn cuối cùng trên kết nối đó.


3
Điều gì xảy ra nếu hai quá trình chèn một hàng cùng một lúc bằng cùng một kết nối. Id nào sẽ insert_idtrở lại?
xiaohan2012

26
@ xiaohan2012 Làm thế nào để 2 quá trình sử dụng cùng một kết nối?
hienbt88

5
lastrowidchỉ có sẵn sau khi giao dịch vãng lai được cam kết?
John Wang

4
@ hienbt88 Có lẽ anh ta có nghĩa là chủ đề, tôi đã làm điều đó và nó có thể gây ra vấn đề trừ khi bạn sử dụng đúng cách an toàn chủ đề. Cá nhân tôi đã bắt đầu tạo một kết nối mới cho mỗi luồng, đó là một cách giải quyết dễ thương vì một số lý do cam kết (thực sự tự động) không hoạt động đối với tôi, tôi đã gặp phải một số vấn đề nghiêm trọng do nhiều luồng đồng thời đưa ra một vài truy vấn môi giây.
Milan Velebit

Không hoạt động với các bản ghi trùng lặp bằng cách sử dụng chèn, chọn và ở đâu.
điện tử

114

Ngoài ra, cursor.lastrowid(tiện ích mở rộng dbapi / PEP249 được hỗ trợ bởi MySQLdb):

>>> import MySQLdb
>>> connection = MySQLdb.connect(user='root')
>>> cursor = connection.cursor()
>>> cursor.execute('INSERT INTO sometable VALUES (...)')
1L
>>> connection.insert_id()
3L
>>> cursor.lastrowid
3L
>>> cursor.execute('SELECT last_insert_id()')
1L
>>> cursor.fetchone()
(3L,)
>>> cursor.execute('select @@identity')
1L
>>> cursor.fetchone()
(3L,)

cursor.lastrowidrẻ hơn connection.insert_id()và rẻ hơn nhiều so với một chuyến đi khứ hồi khác tới MySQL.


4
Tại sao cursor.lastrowidrẻ hơn connection.insert_id()?
Martin Thoma

3
Chỉ vì con trỏ.lastrowid tự động được đặt trên đối tượng con trỏ như một phần của con trỏ.execute () và chỉ là một tra cứu thuộc tính. Connection.insert_id () là một lệnh gọi hàm không cần thiết bổ sung - một lệnh đã được gọi và kết quả có sẵn trên thuộc tính Lastrowid.
Andrew

5
Tôi vừa gặp vấn đề khi cursor.lastrowidtrả lại thứ gì đó khác connection.insert_id(). cursor.lastrowidtrả lại id chèn cuối cùng, connection.insert_id()trả lại 0. Làm thế nào mà có thể được?
Martin Thoma

1
@moose, có thể các quy trình đồng thời đang thực hiện chèn cơ sở dữ liệu song song bằng cách sử dụng cùng một kết nối.
xiaohan2012

1
@FellingAtom, vì điều này đã được chạy trên python2 thay vì python3.
Andrew

35

Thông số DBAPI của Python cũng xác định thuộc tính 'lastrowid' cho đối tượng con trỏ, vì vậy ...

id = cursor.lastrowid

... cũng nên hoạt động và rõ ràng là dựa trên mỗi kết nối.


7
SELECT @@IDENTITY AS 'Identity';

hoặc là

SELECT last_insert_id();

2
điều này cho phép điều kiện cuộc đua bởi vì bạn đang yêu cầu id hàng cuối cùng từ máy chủ. bởi vì tôi, bạn không muốn sự lộn xộn đó
Joshua Burns


1
Tôi muốn chỉ ra phần này cũng quan trọng không kém: "Mỗi khách hàng sẽ nhận được ID được chèn cuối cùng cho câu lệnh cuối cùng mà khách hàng thực hiện." Vì vậy, bạn sẽ nhận được một giá trị khác với Workbench so với việc chạy chính xác select last_insert_id()từ CLI trên máy Linux
đơn giản là mã hóa
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.