MySQLdb, id des grade eingefügten Objektes

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Jutus
User
Beiträge: 5
Registriert: Freitag 18. Dezember 2009, 13:07

Hallo,

ich habe da mal ne Frage. Ich habe eine mySQL Datenbank mit einer Tabelle die automatisch neuen Objekten eine ID zuweist. Wenn ich jetzt mit MySQLdb ein neues Objekt einfüge, wie kann ich die ID des neuen Objektes abfragen?

Ich hab scho in die API gesehen aber noch nichts gefunden, ich weiß auch nicht wirklich wonach ich suchen sollte.
Zuletzt geändert von Jutus am Samstag 19. Dezember 2009, 16:45, insgesamt 1-mal geändert.
Trinkt mehr Milch!
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Jutus hat geschrieben:ich habe da mal ne Frage. Ich habe eine mySQL Datenbank mit einer Tabelle die automatisch neuen Objekten eine ID zuweist. Wenn ich jetzt mit MySQLdb ein neues Objekt einfüge, wie kann ich die ID des neuen Objektes abfragen?

Ich hab scho in die API gesehen aber noch nichts gefunden, ich weiß auch nicht wirklich wonach ich suchen sollte.
Eine Suche mit Google nach mysqldb autoincrement python bringt mich als ersten Treffer zu http://www.mikusa.com/python-mysql-docs ... tions.html und dort finde ich die Methode insert_id(). Schau dir das mal an, das könnte exakt das sein was du suchst.
Jutus
User
Beiträge: 5
Registriert: Freitag 18. Dezember 2009, 13:07

ja, danke damit geht es.

für alle anderen die vielleicht auch danach suchen, der Aufruf könnte so aussehen:

Code: Alles auswählen


mysql = MySQLdb.connect(....)
cursor = mysql.cursor()
cursor.execute("INSERT ....")
id = mysql.insert_id()

Trinkt mehr Milch!
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ah, gut. Eine ähnlich Sache hatte ich letzthin auch. :-)

Frage: gibt insert_id immer die id des zugehörigen Schreibvorgangs zurück oder die des letzten? Wenn es letzten wäre hätte man ja in DBs mit vielen Queries ggf. eine Art Race-Condition und würde nicht automatisch die korrekt ID bekommen...

EDIT: Habe gerade nachgelesen - es kann die "Race-Condition" vorkommen...

Gruß, noisefloor
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

noisefloor hat geschrieben:Frage: gibt insert_id immer die id des zugehörigen Schreibvorgangs zurück oder die des letzten? Wenn es letzten wäre hätte man ja in DBs mit vielen Queries ggf. eine Art Race-Condition und würde nicht automatisch die korrekt ID bekommen...
Inwiefern? Wie sollte man überhaupt den „dazugehörigen“ Schreibvorgang ermitteln können? Und mit einer Race Condition hat das auch nichts zu tun.
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Und mit einer Race Condition hat das auch nichts zu tun.
Nein, mit einer Race-Condition im eigentlichen Sinne nicht. Deswegen hatte ich es in "" gesetzt.

Was ich meine ist, dass man bei dieser Methode nicht automatisch das Ergebnis (=die ID) bekommt, die man "erwartet".

Gruß, noisefloor
BlackJack

Falls ich das nicht falsch verstehe ist das IMHO eine astreine Race-Condition. Das Ergebnis ist davon abhängig welche der beiden Einfügeoperationen das "Rennen" gewinnt.
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

so ähnlich: Die Frage ist, ob die Abfrage der ID oder ein zwischenzeitlich ausgelöster, 2. Schreibquery das Rennen gewinnt.

Jedenfalls ist die Methode daher IMHO für Seiten mit viel Traffic = vielen DB-Zugriffen nicht geeignet.

Ich habe es bei mir so gelöst, dass ich ein

Code: Alles auswählen

SELECT id FROM foobar WHERE spam LIKE 'wert' AND egg LIKE 'wert2' AND usw.
wobei ich die Werte der gerade selber eingefügten Felder abfrage. Das ist sicherlich auch nicht die ultimative Lösung, sollte aber hinreichend "genau" sein, sofern man davon ausgehen kann, dass die Kombination der Werte der eingefügten Felder einmalig ist.

Gruß, noisefloor
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

noisefloor hat geschrieben:Was ich meine ist, dass man bei dieser Methode nicht automatisch das Ergebnis (=die ID) bekommt, die man "erwartet".
Verstehe ich nicht, die bekommt man doch(insert_id ist an die aktuelle Verbindung gebunden, was auf anderen Verbindungen passiert ist egal). Ich meine wenn ich 10 Inserts mache und dann insert_id() kann man nicht erwarten dass man die id vom 1. Insert bekommt. Oder meinst du etwas anderes?
so ähnlich: Die Frage ist, ob die Abfrage der ID oder ein zwischenzeitlich ausgelöster, 2. Schreibquery das Rennen gewinnt.
Das verstehe ich eben nicht, wo soll die 2. Schreibquery herkommen?
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Ich meine wenn ich 10 Inserts mache und dann insert_id() kann man nicht erwarten dass man die id vom 1. Insert bekommt. Oder meinst du etwas anderes?
Ja. :-)
Das verstehe ich eben nicht, wo soll die 2. Schreibquery herkommen?
Genau das ist der Punkt. Wenn du weißt, dass du die Verbindung zur DB exklusiv hast, dann funktioniert das. Wenn du aber z.B. eine stark frequentierte Web-Anwendung hast (z.B. Forum, Wiki...), dann kannst du eben nicht sicher sein, dass dein Abfrage der ID direkt nach deinem Schreib-Query kommt. Daher die Race-Condition.

Zumindest verstehe ich die Aussagen in http://www.mikusa.com/python-mysql-docs ... tions.html so:
Also note that the value of the SQL LAST_INSERT_ID() function always contains the most recently generated AUTO_INCREMENT value, and is not reset between queries because the value of that function is maintained in the server.
Gruß, noisefloor
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Die zitierte Text ist zugegeben nicht eindeutig, aber IMHO MUSS die "last insertion ID" für jede Connection existieren, sodass sich verschiedene Connections nicht in die Quere kommen und es KEINE racing condition gibt. Alles andere wäre ein sehr fragwürdiges Design.

Auch ein stark frequentiertes Forum oder Wiki muss (sollte) pro HTTP request eine Connection benutzen und nicht versuchen, diese (über mehrere threads) wieder zu verwenden. Macht man's hier richtig, würde ich im Gegenzug erwarten, dass MySQL es korrekt macht.

Das lässt sich einfach probieren: Zwei Connections anlegen, in der ersten ein INSERT machen, in der zweiten danach ebenfalls. Jetzt zuerst in der ersten, dann in der zweiten nach der ID fragen.

Stefan
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

noisefloor hat geschrieben:Genau das ist der Punkt. Wenn du weißt, dass du die Verbindung zur DB exklusiv hast, dann funktioniert das. Wenn du aber z.B. eine stark frequentierte Web-Anwendung hast (z.B. Forum, Wiki...), dann kannst du eben nicht sicher sein, dass dein Abfrage der ID direkt nach deinem Schreib-Query kommt. Daher die Race-Condition.
Das ist dann wirklich ein klarer Fall von selbst Schuld. Normalerweise hat man eine Verbindung exklusiv. Wenn nicht, dann hast du die selber „freigegeben“. Wenn du das gemacht hast, dann sollte es ein leichtes sein, die Verbindung für dieses Moment zu „locken“, deine zwei Abfragen abzusetzen und dann wieder freizugeben.

Eine wirkliche Race-Condition sehe ich nur, wenn sich verschiedene Verbindungen in die Quere kommen könnten, das tun sie aber nicht.
http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id hat geschrieben: The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@Darli: THX, das ist eindeutig. :-) Also entspannen ;-)

Gruß, noisefloor
Antworten