[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