Wie erhalte ich die "ID" nach dem Einfügen in die MySQL-Datenbank mit Python?

182

Ich führe eine INSERT INTO-Anweisung aus

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

und ich möchte den Primärschlüssel bekommen.

Meine Tabelle hat 2 Spalten:

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

Wie erhalte ich die "ID", nachdem ich diese gerade eingefügt habe?

TIMEX
quelle

Antworten:

242

Verwenden Sie cursor.lastrowiddiese Option , um die letzte in das Cursorobjekt eingefügte Zeilen-ID oder connection.insert_id()die ID der letzten Einfügung in diese Verbindung abzurufen.

Bernstein
quelle
3
Was ist, wenn zwei Prozesse gleichzeitig eine Zeile über dieselbe Verbindung einfügen? Welche ID wird insert_idzurückkehren?
Xiaohan2012
26
@ xiaohan2012 Wie verwenden 2 Prozesse dieselbe Verbindung?
hienbt88
5
Ist lastrowiderst verfügbar, nachdem die aktuelle Transaktion festgeschrieben wurde?
John Wang
4
@ hienbt88 Er meinte wahrscheinlich Threads, das habe ich getan und es kann Probleme verursachen, wenn Sie die Thread-Sicherheit nicht richtig nutzen. Ich persönlich habe versucht, für jeden Thread eine neue Verbindung herzustellen, was eine nette Problemumgehung ist, da das Festschreiben (eigentlich das automatische Festschreiben) aus irgendeinem Grund bei mir nicht funktioniert hat. Aufgrund vieler gleichzeitiger Threads, die alle einige Abfragen ausgaben, kam es zu ernsthaften Verflechtungen pro Sekunde.
Milan Velebit
Funktioniert nicht mit doppelten Datensätzen mit Einfügen, Auswählen und Wo.
E-Info128
114

Außerdem cursor.lastrowid(eine von MySQLdb unterstützte dbapi / PEP249-Erweiterung):

>>> 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.lastrowidist etwas billiger als connection.insert_id()und viel billiger als eine weitere Rundreise zu MySQL.

Andrew
quelle
4
Warum ist cursor.lastrowidbilliger als connection.insert_id()?
Martin Thoma
3
Nur weil cursor.lastrowid als Teil von cursor.execute () automatisch für das Cursorobjekt festgelegt wird und nur eine Attributsuche ist. connection.insert_id () ist ein zusätzlicher unnötiger Funktionsaufruf - ein Aufruf, der bereits aufgerufen wurde und dessen Ergebnis für das Attribut lastrowid verfügbar ist.
Andrew
5
Ich hatte gerade ein Problem, bei dem cursor.lastrowidetwas anderes zurückgegeben wurde als connection.insert_id(). cursor.lastrowidgab die letzte Einfügungs-ID zurück, connection.insert_id()zurückgegeben 0. Wie kann das sein?
Martin Thoma
1
@moose, möglicherweise führen gleichzeitige Prozesse das parallele Einfügen von Datenbanken über dieselbe Verbindung durch.
Xiaohan2012
1
@FlyingAtom, da dies auf Python2 anstelle von Python3 ausgeführt wurde.
Andrew
35

Die Python-DBAPI-Spezifikation definiert auch das Attribut 'lastrowid' für das Cursorobjekt.

id = cursor.lastrowid

... sollte auch funktionieren, und es basiert offensichtlich auf jeder Verbindung.

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

oder

SELECT last_insert_id();
Keith
quelle
2
Dies ermöglicht Rennbedingungen, da Sie die letzte Zeilen-ID vom Server anfordern. wegen mir willst du dieses Durcheinander nicht.
Joshua Burns
1
Ich möchte darauf hinweisen, dass dieser Teil ebenso wichtig ist: "Jeder Client erhält die zuletzt eingefügte ID für die letzte Anweisung, die der Client ausgeführt hat." Sie erhalten also einen anderen Wert von Workbench, als wenn Sie genau denselben Wert von select last_insert_id()der CLI auf einem Linux-Computer
ausführen