Bagaimana saya mendapatkan "id" setelah INSERT ke dalam database MySQL dengan Python?

183

Saya menjalankan pernyataan INSERT INTO

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

dan saya ingin mendapatkan kunci utama.

Meja saya memiliki 2 kolom:

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

Bagaimana saya mendapatkan "id", setelah saya baru saja memasukkan ini?

TIMEX
sumber

Jawaban:

243

Gunakan cursor.lastrowiduntuk memasukkan ID baris terakhir pada objek kursor, atau connection.insert_id()untuk mendapatkan ID dari insert terakhir pada koneksi itu.

Amber
sumber
3
Bagaimana jika dua proses menyisipkan baris secara bersamaan menggunakan koneksi yang sama. Id mana yang akan insert_idkembali?
xiaohan2012
27
@ xiaohan2012 Bagaimana 2 proses menggunakan koneksi yang sama?
hienbt88
5
Apakah lastrowidhanya tersedia setelah transaksi saat ini dilakukan?
John Wang
4
@ hienbt88 Mungkin maksudnya adalah utas, saya sudah melakukannya dan itu dapat menyebabkan masalah kecuali Anda menggunakan utas keselamatan dengan benar. Saya pribadi mencari instantiasi koneksi baru untuk setiap utas, yang merupakan solusi lucu karena untuk beberapa alasan melakukan (sebenarnya autocommitting) tidak berfungsi untuk saya, saya mendapat jalinan yang serius karena banyak utas bersamaan yang semuanya mengeluarkan beberapa pertanyaan per detik.
Milan Velebit
Tidak berfungsi dengan rekaman duplikat menggunakan sisipkan, pilih dan di mana.
e-info128
114

Juga, cursor.lastrowid(ekstensi dbapi / PEP249 didukung oleh 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.lastrowidagak lebih murah daripada connection.insert_id()dan jauh lebih murah daripada pulang pergi ke MySQL.

Andrew
sumber
4
Kenapa cursor.lastrowidlebih murah dari itu connection.insert_id()?
Martin Thoma
3
Hanya karena cursor.lastrowid secara otomatis ditetapkan pada objek kursor sebagai bagian dari cursor.execute () dan hanya pencarian atribut. connection.insert_id () adalah panggilan fungsi tambahan yang tidak perlu - yang sudah dipanggil dan yang hasilnya tersedia pada atribut lastrowid.
Andrew
5
Saya baru saja mengalami masalah di mana cursor.lastrowidmengembalikan sesuatu yang berbeda dari connection.insert_id(). cursor.lastrowidmengembalikan id sisipan terakhir, connection.insert_id()dikembalikan 0. Bagaimana itu bisa terjadi?
Martin Thoma
1
@moose, mungkin proses bersamaan melakukan penyisipan database paralel menggunakan koneksi yang sama.
xiaohan2012
1
@ FlyingAtom, karena ini dijalankan di python2 bukan python3.
Andrew
35

Python DBAPI spec juga mendefinisikan atribut 'lastrowid' untuk objek kursor, jadi ...

id = cursor.lastrowid

... harus bekerja juga, dan itu berdasarkan koneksi per jelas.

Htechno
sumber
7
SELECT @@IDENTITY AS 'Identity';

atau

SELECT last_insert_id();
Keith
sumber
2
ini memungkinkan untuk kondisi balapan karena Anda meminta id baris terakhir dari server. karena saya, Anda tidak ingin kekacauan itu.
Joshua Burns
1
Saya ingin menunjukkan bagian ini sama pentingnya: "Setiap klien akan menerima ID yang dimasukkan terakhir untuk pernyataan terakhir yang dieksekusi klien." Jadi, Anda akan mendapatkan nilai yang berbeda dari Workbench daripada menjalankan yang sama persis select last_insert_id()dari CLI pada mesin Linux
coding
0

Ini mungkin hanya persyaratan PyMySql dengan Python, tetapi saya menemukan bahwa saya harus memberi nama tabel yang tepat yang saya inginkan untuk ID:

Di:

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

Keluar: 5
... atau apa pun nilai Batch_ID yang benar sebenarnya

Edward
sumber
@ krzys_h Terima kasih telah melihat K ini tetapi hasil edit Anda gagal dalam pengujian saya dan karenanya saya telah menolak hasil edit Anda. Jika Anda tidak keberatan juga mendukung pengeditan?
Edward