[Python-de] Möglicher Fehler im Postgres-Treiber 'pg8000'

Volker Böhm volker at vboehm.de
Sa Apr 13 17:49:52 CEST 2013


Hallo,
beim Versuch mit dem Modul 'pg8000' auf eine Postgres-Datenbank 
zuzugreifen bin ich auf einen Fehler gestoßen, der meiner Meinung nach im 
pg8000 enthalten ist.

Das Programm macht eine Query und arbeitet der Reihe nach alle Sätze ab. 
Dabei erstellt es neue Sätze für eine andere Tabelle, die dort mit INSERT 
hineingeschrieben werden. Wenn ich alle Sätze verarbeite und zum Schluss 
erst ein COMMIT mache, geht alles gut. 
Da das Originalprogramm aber ca. 450.000 Sätze verarbeitet und dabei mehr 
als 2.000.000 neue Sätze in die Ziel-Tabelle schreibt, wofür es ca. 100 
Stunden braucht, wollte ich natürlich zwischendurch gelegentlich ein 
COMMIT machen. Wenn ich dies tue bricht das Programm aber kurze Zeit 
später - genauer nach 100 Sätzen - mit dem Fehler
    pg8000.errors.ProgrammingError: ('ERROR', '34000', 
        'portal "pg8000_portal_10007" does not exist')
ab.

Ich habe das Programm soweit vereinfacht, dass sich der Fehler 
reproduzieren lässt:

--------- schnipp ---------------------------------------------
#!/usr/bin/env python

import random
from pg8000 import DBAPI as DB
#import psycopg2 as DB
#import pgdb as DB

random.seed()
conn = DB.connect(host = 'myhost', database = 'mydb',
    port = 5432, user = 'me', password = 'mypwd')
cur1 = conn.cursor()
cur2 = conn.cursor()

#------------------- Tabellen erstellen -----------------------
cur1.execute('DROP TABLE IF EXISTS t1')
cur1.execute('''
    create table t1 (
        a integer,
        b integer)''')
cur1.execute('DROP TABLE IF EXISTS t2')
cur1.execute('''
    create table t2 (
        c integer,
        d integer)''')
#------------------- t1 befüllen ------------------------------
for i in range(10000):
    cur1.execute('''
        INSERT INTO t1(a,b)
        VALUES(%s, %s)''',
        (random.randint(1, 1000000), random.randint(1, 1000000)))
conn.commit()

#------------------- Hier geht's los --------------------------
cur1.execute('''
    SELECT a,b
    FROM t1''');
row = cur1.fetchone()
while row:
    print row
    a, b = row
    cur2.execute('''
        INSERT INTO t2(c, d)
        VALUES(%s, %s)''',(3*a, 5*b))
    conn.commit()
    row = cur1.fetchone()
conn.close()
--------- schnapp ---------------------------------------------

Habe ich etwas übersehen oder mache ich etwas Prinzipielles falsch?

Wenn ich 'psycopg2' oder 'PygeSQL' als Treiber benutze (Tausch der IMPORT-
Zeilen), tritt der Fehler nicht auf.

Es sieht so aus, als würde der COMMIT-Befehl den Cursor cur1 Schließen 
und dann nur noch die restlichen gepufferten Sätze gelesen werden. Es 
kommt übrigens nicht auf die Anzahl der geschriebenen Sätze oder die 
Anzahl der COMMITs an: Ein einziges COMMIT sorgt dafür, dass nach 100 
Sätzen Schluss ist.

mfg  Volker
-- 
Volker Böhm         Tel.: +49 4141 981152         www.vboehm.de
Voßkuhl 5           Fax:  +49 4141 981154
D-21682 Stade       mailto:volker at vboehm.de


Mehr Informationen über die Mailingliste python-de