¿Cómo obtengo el "id" después de INSERTAR en la base de datos MySQL con Python?


183

Ejecuto una instrucción INSERT INTO

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

y quiero obtener la clave primaria.

Mi mesa tiene 2 columnas:

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

¿Cómo obtengo el "id" después de insertar esto?


Respuestas:


244

Use cursor.lastrowidpara obtener la última ID de fila insertada en el objeto del cursor, o connection.insert_id()para obtener la ID de la última inserción en esa conexión.


3
¿Qué sucede si dos procesos insertan una fila al mismo tiempo usando la misma conexión? ¿Qué identificación volverá insert_id?
xiaohan2012

28
@ xiaohan2012 ¿Cómo utilizan 2 procesos la misma conexión?
hienbt88

55
¿ lastrowidSolo está disponible después de que se confirme la transacción actual?
John Wang

44
@ hienbt88 Probablemente se refería a hilos, lo he hecho y puede causar problemas a menos que utilice correctamente la seguridad de hilos. Personalmente, he decidido crear una nueva conexión para cada subproceso, lo cual es una linda solución, ya que por alguna razón el compromiso (en realidad, la confirmación automática) no funcionó para mí, obtuve algunos entrelazamientos serios debido a que muchos subprocesos concurrentes emitieron algunas consultas. por segundo.
Milan Velebit

No funciona con registros duplicados usando insertar, seleccionar y dónde.
e-info128

114

Además, cursor.lastrowid(una extensión dbapi / PEP249 compatible con 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.lastrowides algo más barato connection.insert_id()y mucho más barato que otro viaje de ida y vuelta a MySQL.


44
¿Por qué es cursor.lastrowidmás barato que connection.insert_id()?
Martin Thoma

3
Solo porque cursor.lastrowid se establece automáticamente en el objeto cursor como parte de cursor.execute () y es solo una búsqueda de atributos. connection.insert_id () es una llamada de función innecesaria adicional, una que ya se ha llamado y cuyo resultado está disponible en el atributo lastrowid.
Andrew

55
Acabo de tener un problema al cursor.lastrowiddevolver algo diferente a connection.insert_id(). cursor.lastrowiddevolvió la última identificación de inserción, connection.insert_id()devuelta 0. ¿Como puede ser?
Martin Thoma

1
@moose, quizás los procesos concurrentes están haciendo una inserción paralela de la base de datos utilizando la misma conexión.
xiaohan2012

1
@FlyingAtom, porque esto se ejecutó en python2 en lugar de python3.
Andrew

35

La especificación DBAPI de Python también define el atributo 'lastrowid' para el objeto cursor, así que ...

id = cursor.lastrowid

... también debería funcionar, y obviamente se basa en la conexión.


7
SELECT @@IDENTITY AS 'Identity';

o

SELECT last_insert_id();

2
esto permite condiciones de carrera porque está solicitando la última fila de identificación del servidor. porque yo no quieres ese desastre.
Joshua Burns


1
Quiero señalar que esta parte es igualmente importante: "Cada cliente recibirá la última ID insertada para la última declaración que ejecutó el cliente". Por lo tanto, obtendrá un valor diferente de Workbench que ejecutar exactamente lo mismo select last_insert_id()desde la CLI en una máquina Linux
simplemente codificando el

0

Esto podría ser solo un requisito de PyMySql en Python, pero descubrí que tenía que nombrar la tabla exacta para la que deseaba la ID:

En:

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

Fuera: 5
... o cualquiera que sea el valor correcto de Batch_ID


@krzys_h Gracias por mirar este K, pero su edición falla en mis pruebas y por eso he rechazado su edición. ¿Si no te importaría también respaldar la edición?
Edward
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.