ID mit cur.lastrowid bei PostgreSQL

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Freitag 3. November 2006, 20:06

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
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 3. November 2006, 21:46

Byte hat geschrieben:den automatisch erzeugten Schlüssel(serial), bei einem INSERT, zurückzuerhalten?
Hallo Christian!

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.
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Samstag 4. November 2006, 17:49

Hallo,

@Gerold
Danke für deine schnelle Unterstützung. :D


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()
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
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Montag 13. November 2006, 19:49

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
Benutzeravatar
jens
Moderator
Beiträge: 8481
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 14. November 2006, 09:46

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

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Dienstag 14. November 2006, 16:34

Hi Jens,
Ich hab zwar noch nichts mit PostgreSQL am Hut, aber sollte nicht am Cursor das Attribute .lastrowid kleben???
Es sollte definitiv so sein, dass diese Attribut von psycopg2 nicht unterstützt wird.

Aber die Lösung mit lastval oder nextval finde ich ganz annehmbar.

Gruß Christian
Benutzeravatar
jens
Moderator
Beiträge: 8481
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 14. November 2006, 16:59

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):

Code: Alles auswählen

if not hasattr(cursor, 'lastrowid'):
    cursor.lastrowid = psycopg2.lastval

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
tabellar
User
Beiträge: 186
Registriert: Mittwoch 4. September 2002, 15:28

Dienstag 14. November 2006, 21:18

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
Antworten