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.
MySQLdb, id des grade eingefügten Objektes
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 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.
ja, danke damit geht es.
für alle anderen die vielleicht auch danach suchen, der Aufruf könnte so aussehen:
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!
- 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
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
Inwiefern? Wie sollte man überhaupt den „dazugehörigen“ Schreibvorgang ermitteln können? Und mit einer Race Condition hat das auch nichts zu tun.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...
- noisefloor
- User
- Beiträge: 4149
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Was ich meine ist, dass man bei dieser Methode nicht automatisch das Ergebnis (=die ID) bekommt, die man "erwartet".
Gruß, noisefloor
Nein, mit einer Race-Condition im eigentlichen Sinne nicht. Deswegen hatte ich es in "" gesetzt.Und mit einer Race Condition hat das auch nichts zu tun.
Was ich meine ist, dass man bei dieser Methode nicht automatisch das Ergebnis (=die ID) bekommt, die man "erwartet".
Gruß, noisefloor
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.
- 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
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
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.
Gruß, noisefloor
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?noisefloor hat geschrieben:Was ich meine ist, dass man bei dieser Methode nicht automatisch das Ergebnis (=die ID) bekommt, die man "erwartet".
Das verstehe ich eben nicht, wo soll die 2. Schreibquery herkommen?so ähnlich: Die Frage ist, ob die Abfrage der ID oder ein zwischenzeitlich ausgelöster, 2. Schreibquery das Rennen gewinnt.
- noisefloor
- User
- Beiträge: 4149
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Ja.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?

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 verstehe ich eben nicht, wo soll die 2. Schreibquery herkommen?
Zumindest verstehe ich die Aussagen in http://www.mikusa.com/python-mysql-docs ... tions.html so:
Gruß, noisefloorAlso 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.
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
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
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.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.
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.
- 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
@Darli: THX, das ist eindeutig.


Gruß, noisefloor