วิธีการดึง id ที่ใส่เข้าไปหลังจากแทรกแถวใน SQLite โดยใช้ Python


176

วิธีการดึง id ที่ใส่เข้าไปหลังจากแทรกแถวใน SQLite โดยใช้ Python ฉันมีโต๊ะแบบนี้:

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

ผมแทรกแถวใหม่ที่มีข้อมูลตัวอย่างและusername="test" password="test"ฉันจะดึงข้อมูลรหัสที่สร้างขึ้นในวิธีการทำธุรกรรมได้อย่างปลอดภัย นี่เป็นวิธีการแก้ปัญหาเว็บไซต์โดยที่คนสองคนอาจแทรกข้อมูลในเวลาเดียวกัน ฉันรู้ว่าฉันสามารถอ่านแถวสุดท้ายได้ แต่ฉันไม่คิดว่าธุรกรรมนั้นปลอดภัย ใครสามารถให้คำแนะนำได้บ้าง

คำตอบ:


256

คุณสามารถใช้cursor.lastrowid (ดูที่ "ส่วนเสริม DB API เสริม"):

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

หากคนสองคนกำลังแทรกในเวลาเดียวกันตราบใดที่พวกเขากำลังใช้cursors ที่แตกต่างกันcursor.lastrowidจะส่งกลับidแถวสุดท้ายที่cursorแทรกไว้:

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

โปรดทราบว่าlastrowidผลตอบแทนNoneเมื่อคุณแทรกมากกว่าหนึ่งแถวพร้อมexecutemanyกัน:

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

16
+1 สำหรับการอธิบายว่ามันจะส่งคืน id ล่าสุดโดยเคอร์เซอร์แต่ละอินสแตนซ์
quakkels

43
นอกจากนี้ยังมีlast_insert_rowid()ฟังก์ชัน SQLช่วยให้คุณสามารถแทรก id แถวสุดท้ายเป็น foreign key ในคำสั่ง insert ครั้งถัดไปทั้งหมดใน SQL
Martijn Pieters

2
@MartijnPieters คุณสามารถโพสต์ได้ว่าเป็นคำตอบแม้ว่าคำถามจะค่อนข้างเก่า มันอาจจะยังคงช่วยให้ผู้ใช้อ่านหน้านี้
Daniel Werner

3
ปรากฏใช้ sqlite3 ของ Python lastrowid ใช้last_insert_rowidภายใต้github.com/ghaering/pysqlite/blob/ ...... (ซึ่งไม่ได้รับประกัน threadsafe แต่ดูเหมือนตัวเลือกเดียว FWIW) ดูstackoverflow.com/q/2127138/32453
rogerdpack

2
Btw นี้ทำงานให้แต่ไม่ได้ทำงานINSERT UPDATEแต่เมื่อทำการอัปเดตแถวคุณอาจมี ID แถวที่สอดคล้องกันอยู่แล้ว (เพิ่งพาฉันไปสักพักเพื่อคิดออก ... )
CGFoX

4

เครดิตทั้งหมดให้กับ@Martijn Pietersในความคิดเห็น:

คุณสามารถใช้ฟังก์ชั่นlast_insert_rowid():

last_insert_rowid()ฟังก์ชันส่งกลับROWIDของแทรกแถวสุดท้ายจากการเชื่อมต่อฐานข้อมูลที่เรียกฟังก์ชั่น last_insert_rowid()ฟังก์ชั่น SQL เป็นเสื้อคลุมรอบsqlite3_last_insert_rowid()ฟังก์ชั่นอินเตอร์เฟซ C / C ++

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