Hi,
hat irgendwer eine Ahnung, wie man es schafft, bei Psycopg2, den automatisch erzeugten Schlüssel(serial), bei einem INSERT, zurückzuerhalten?
Habe es mit cur.lastrowid probiert, das scheint aber nicht zu gehen, hat die Pythondoku zu diesem Befehl schon angedeutet.
Die Doku unter http://initd.org/pub/software/psycopg/d ... amming.pdf , kommt mir auch so vor als wäre sie noch nicht fertig.
Gibt es bessere Quellen, was alles möglich ist?
Gruß Christian
ID mit cur.lastrowid bei PostgreSQL
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Christian!Byte hat geschrieben:den automatisch erzeugten Schlüssel(serial), bei einem INSERT, zurückzuerhalten?
Dazu gab es im September eine interessante Diskussion in der Newsgroup "comp.lang.python".
--> hier <--
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Hallo,
@Gerold
Danke für deine schnelle Unterstützung.
Meine Lösung:
Funktion:
Vor dem INSERT - Befehl wird mit SELECT nextval die nächste ID der Tabelle geholt. Die ID ist eine Spalte vom Datentyp Serial.
Der INSERT - Befehl wir dann mit expliziter Angabe der ID ausgeführt, somit ist die ID für weiter Verarbeitung bekannt.
Habe es bei mir getestet und funktioniert bisher ohne Fehler. In dem Link von Gerold war glaube ich curval der Favorit, da mein Englisch aber nicht so perfekt ist, kann ich das nicht so genau sagen.
nextval(sequenz): Erhöht die Sequenz zum nächsten Wert und gibt diesen Wert zurück. Wenn mehrere Sitzungen nextval gleichzeitig aufrufen, erhält jede Sitzung einen unterschiedlichen Sequenzwert.
Das sollte genau das sein was gebraucht wird.
currval(sequenz): Gibt den Wert zurück, der zuletzt in der aktuellen Sitzung von nextval für die Sequenz zurückgeben wurde.
Mit currval tritt ein Fehler auf wenn noch kein nextval in der Sitzung ausgeführt wurde. Und der Wert wird nicht neu generiert solange kein weiteres nextval ausgeführt wird.
Gruß Christian
@Gerold
Danke für deine schnelle Unterstützung.
Meine Lösung:
Code: Alles auswählen
con = pg.connect("host=*host* dbname=*db* user=*user* password=*pw*")
cur = con.cursor()
cur.execute("SELECT nextval(pg_get_serial_sequence('*Tabelle*', '*IDSpalte*'))")
newid=cur.fetchone()[0]
sql = "INSERT INTO *Tabelle* (*IDSpalte*, *AndereSpalte*) values ('%s','%s')" % (newid,'*Wert*')
cur.execute(sql)
con.commit()
Vor dem INSERT - Befehl wird mit SELECT nextval die nächste ID der Tabelle geholt. Die ID ist eine Spalte vom Datentyp Serial.
Der INSERT - Befehl wir dann mit expliziter Angabe der ID ausgeführt, somit ist die ID für weiter Verarbeitung bekannt.
Habe es bei mir getestet und funktioniert bisher ohne Fehler. In dem Link von Gerold war glaube ich curval der Favorit, da mein Englisch aber nicht so perfekt ist, kann ich das nicht so genau sagen.
nextval(sequenz): Erhöht die Sequenz zum nächsten Wert und gibt diesen Wert zurück. Wenn mehrere Sitzungen nextval gleichzeitig aufrufen, erhält jede Sitzung einen unterschiedlichen Sequenzwert.
Das sollte genau das sein was gebraucht wird.
currval(sequenz): Gibt den Wert zurück, der zuletzt in der aktuellen Sitzung von nextval für die Sequenz zurückgeben wurde.
Mit currval tritt ein Fehler auf wenn noch kein nextval in der Sitzung ausgeführt wurde. Und der Wert wird nicht neu generiert solange kein weiteres nextval ausgeführt wird.
Gruß Christian
Hi,
nochmal ein Nachtrag, sieht so aus als ob auch lastval() nach dem Einfügen benutzt werden könnte.
http://www.pg-forum.de/showthread.php?t=708
Habe ich aber noch nicht getestet!
HTH
Christian
nochmal ein Nachtrag, sieht so aus als ob auch lastval() nach dem Einfügen benutzt werden könnte.
http://www.pg-forum.de/showthread.php?t=708
Habe ich aber noch nicht getestet!
HTH
Christian
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Ich hab zwar noch nichts mit PostgreSQL am Hut, aber sollte nicht am Cursor das Attribute .lastrowid kleben???
Sollte zumindest laut DB-API http://www.python.org/peps/pep-0249.html so sein.
Ich hatte da allerdings auch mal das selbe Problem mit MySQLdb. Meine Lösung: http://www.python-forum.de/post-29014.html#29014
Sollte zumindest laut DB-API http://www.python.org/peps/pep-0249.html so sein.
Ich hatte da allerdings auch mal das selbe Problem mit MySQLdb. Meine Lösung: http://www.python-forum.de/post-29014.html#29014
Hi Jens,
Aber die Lösung mit lastval oder nextval finde ich ganz annehmbar.
Gruß Christian
Es sollte definitiv so sein, dass diese Attribut von psycopg2 nicht unterstützt wird.Ich hab zwar noch nichts mit PostgreSQL am Hut, aber sollte nicht am Cursor das Attribute .lastrowid kleben???
Aber die Lösung mit lastval oder nextval finde ich ganz annehmbar.
Gruß Christian
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Das ist allerdings IMHO dumm gelöst... Vielleicht sollte man das mal als FeatureRequest bei psycopg2 einreichen...
Man kann allerdings doch meine Lösung nehmen und lastval am Cursor als lastrowid binden... Zumindest solange, bis psycopg2 das selber macht...
So z.B. (ungetestet):
Man kann allerdings doch meine Lösung nehmen und lastval am Cursor als lastrowid binden... Zumindest solange, bis psycopg2 das selber macht...
So z.B. (ungetestet):
Code: Alles auswählen
if not hasattr(cursor, 'lastrowid'):
cursor.lastrowid = psycopg2.lastval
Postgres stellt nicht umsonst die serverseitigen Funktion nextval, currval,
setval und lastval zur Steuerung der jeweiligen Sequenzzähler zur Verfügung.
nextval('sequenz_name')
Gibt die nächste freie Sequenznummer zurück und aktualisiert den Zähler
currval('sequenz_name')
Gibt die Sequenznummer des letzten Aufrufs von nextval('sequenz_name') zurück
setval('sequenz_name', newval)
Setzt den Zähler der Sequenznummer auf den angegebenen Wert
lastval()
Gibt die Sequenznummer des letzten generellen Aufrufs von nextval('sequenz_name') zurück.
Diese Sequenzfunktionen sind sitzungsbezogen und sind von nextval()
Aufrufen anderen Benutzer nicht beeinflusst.
Tabellar
setval und lastval zur Steuerung der jeweiligen Sequenzzähler zur Verfügung.
nextval('sequenz_name')
Gibt die nächste freie Sequenznummer zurück und aktualisiert den Zähler
currval('sequenz_name')
Gibt die Sequenznummer des letzten Aufrufs von nextval('sequenz_name') zurück
setval('sequenz_name', newval)
Setzt den Zähler der Sequenznummer auf den angegebenen Wert
lastval()
Gibt die Sequenznummer des letzten generellen Aufrufs von nextval('sequenz_name') zurück.
Diese Sequenzfunktionen sind sitzungsbezogen und sind von nextval()
Aufrufen anderen Benutzer nicht beeinflusst.
Tabellar