ฉันจะรับ“ id” หลังจาก INSERT ลงในฐานข้อมูล MySQL ด้วย Python ได้อย่างไร


183

ฉันรันคำสั่ง INSERT INTO

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

และฉันต้องการได้รับคีย์หลัก

ตารางของฉันมี 2 คอลัมน์:

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

ฉันจะได้รับ "id" หลังจากที่ฉันใส่มันได้อย่างไร


คำตอบ:


243

ใช้cursor.lastrowidเพื่อรับ ID แถวสุดท้ายที่แทรกบนวัตถุเคอร์เซอร์หรือconnection.insert_id()เพื่อรับ ID จากการแทรกครั้งล่าสุดในการเชื่อมต่อนั้น


3
จะเกิดอะไรขึ้นถ้าสองกระบวนการแทรกแถวในเวลาเดียวกันโดยใช้การเชื่อมต่อเดียวกัน รหัสใดจะinsert_idกลับมา?
xiaohan2012

27
@ xiaohan2012 กระบวนการ 2 กระบวนการใช้การเชื่อมต่อเดียวกันได้อย่างไร
hienbt88

5
คือlastrowidใช้ได้เฉพาะหลังจากที่การทำธุรกรรมในปัจจุบันจะมุ่งมั่น?
John Wang

4
@ hienbt88 เขาอาจหมายถึงเธรดฉันได้ทำไปแล้วและอาจทำให้เกิดปัญหาได้เว้นแต่คุณจะใช้เธรดอย่างปลอดภัย ฉันไปเป็นการส่วนตัวเพื่อสร้างการเชื่อมต่อใหม่สำหรับแต่ละเธรดซึ่งเป็นวิธีแก้ปัญหาที่น่ารักเนื่องจากด้วยเหตุผลบางอย่างที่ทำให้ (การเติมข้อความอัตโนมัติ) ไม่ทำงานสำหรับฉัน ต่อวินาที.
Milan Velebit

ไม่ทำงานกับระเบียนที่ซ้ำกันโดยใช้การแทรกเลือกและตำแหน่ง
e-info128

114

นอกจากนี้cursor.lastrowid(ส่วนขยาย dbapi / PEP249 รองรับโดย 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.lastrowidค่อนข้างถูกกว่าconnection.insert_id()และถูกกว่ามากอีกหนึ่งการเดินทางไปยัง MySQL


4
ทำไมจึงcursor.lastrowidมีราคาถูกกว่าconnection.insert_id()?
Martin Thoma

3
เนื่องจาก cursor.lastrowid ถูกตั้งค่าโดยอัตโนมัติบนวัตถุเคอร์เซอร์เป็นส่วนหนึ่งของ cursor.execute () และเป็นเพียงการค้นหาแอ็ตทริบิวต์ connection.insert_id () เป็นการเรียกใช้ฟังก์ชันที่ไม่จำเป็นเพิ่มเติม - ซึ่งได้ถูกเรียกใช้แล้วและมีผลลัพธ์ในแอตทริบิวต์ lastrowid
Andrew

5
ฉันเพิ่งมีปัญหาที่กลับสิ่งที่แตกต่างcursor.lastrowid กลับรหัสแทรกที่ผ่านมากลับมา เป็นไปได้อย่างไร? connection.insert_id()cursor.lastrowidconnection.insert_id()0
Martin Thoma

1
@moose กระบวนการที่เกิดขึ้นพร้อมกันอาจกำลังทำการแทรกฐานข้อมูลแบบขนานโดยใช้การเชื่อมต่อเดียวกัน
xiaohan2012

1
@FlyingAtom เพราะนี่ทำงานบน python2 แทนที่จะเป็น python3
Andrew

35

Python DBAPI spec ยังกำหนดคุณลักษณะ 'lastrowid' สำหรับวัตถุเคอร์เซอร์ดังนั้น ...

id = cursor.lastrowid

... ควรใช้งานได้เช่นกันและขึ้นอยู่กับการเชื่อมต่อ


7
SELECT @@IDENTITY AS 'Identity';

หรือ

SELECT last_insert_id();

2
สิ่งนี้ทำให้เกิดสภาวะการแข่งขันเนื่องจากคุณกำลังขอรหัสแถวสุดท้ายจากเซิร์ฟเวอร์ เพราะฉันคุณไม่ต้องการความยุ่งเหยิงนั้น
Joshua Burns


1
ฉันต้องการชี้ให้เห็นว่าส่วนนี้มีความสำคัญเท่าเทียมกัน: "ลูกค้าแต่ละรายจะได้รับ ID ที่แทรกล่าสุดสำหรับคำสั่งสุดท้ายที่ลูกค้าดำเนินการ" ดังนั้นคุณจะได้รับค่าที่แตกต่างจาก Workbench กว่าทำงานเดียวกันแน่นอนselect last_insert_id()จาก CLI บนเครื่อง Linux
simplycoding

0

นี่อาจเป็นเพียงข้อกำหนดของ PyMySql ใน Python แต่ฉันพบว่าฉันต้องตั้งชื่อตารางที่แน่นอนที่ฉันต้องการ ID สำหรับ:

ใน:

cnx = pymysql.connect(host='host',
                            database='db',
                            user='user',
                            password='pass')
cursor = cnx.cursor()
update_batch = """insert into batch set type = "%s" , records = %i, started = NOW(); """
second_query = (update_batch % ( "Batch 1", 22  ))
cursor.execute(second_query)
cnx.commit()
batch_id = cursor.execute('select last_insert_id() from batch')
cursor.close()

batch_id

ออก: 5
... หรือค่า Batch_ID ที่ถูกต้องจริง ๆ คืออะไร


@krzys_h ขอบคุณที่ดู K นี้ แต่การแก้ไขของคุณล้มเหลวในการทดสอบของฉันและฉันได้ปฏิเสธการแก้ไขของคุณ หากคุณไม่รังเกียจที่จะสำรองข้อมูลการแก้ไขด้วย
Edward
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.