[Python] [Python e PostgreSQL] All'interno delle eccezioni, le transazioni si comportano diversamente?
Daniele Varrazzo
piro a develer.com
Lun 25 Ott 2010 11:53:57 CEST
On Mon, 25 Oct 2010 00:00:34 +0200, Marco Fochesato <marcofoc a libero.it>
wrote:
>> Grazie per la versione. Vorrei vedere un pezzetto di codice con le
>> operazioni che svolgi: la query, l'eccezione, la query
>> *nell'*eccezione...
> try:
> cur.execute(update, (nuovo_valore, valore_statico))
> connDB.commit()
> except psycopg2.IntegrityError:
> connDB = psycopg2.connect(connessione)
> cur = connDB.cursor()
Se l'execute(update) può dare un'eccezione, puoi usare una transazione
annidiata con SAVEPOINT per mantenere la sessione integra:
cur.execute("SAVEPOINT tmp;")
try:
cur.execute(update, (nuovo_valore, valore_statico))
except psycopg2.IntegrityError:
cur.execute("ROLLBACK TO tmp;")
cur.execute( ... quello che fai on caso di errore)
else:
# quello che fai se non c'e' stato errore
finally:
connDB.commit()
cur.close()
connDB.close()
Vedi http://www.postgresql.org/docs/9.0/static/sql-savepoint.html per la
doc.
> Non ho mai postato del codice.. spero non si dovesse far in altra
> maniera.
> Le varie variabili, sono state dichiarate prima.. ma credo vadano bene
> tutte. Il problema è proprio nel primo update. Mi dà errore perchè
> cambio ina idnazione non ancora presente nella tabella nazioni..
Questo esempio non è quello che avrei definito auto-contenuto: stavamo
parlando di psycopg che si comporta in auto-commit in qualche condizione
collegata a creare connessioni nell'eccezione, no? Speravo in codice che
testasse solo questo :)
Io per conto mio ho provato:
import psycopg2
def test(dsn):
"""test if a connection created in an exception handler goes
autocommit"""
cnn = psycopg2.connect(dsn)
cur = cnn.cursor()
cur.execute("""drop table if exists test;""")
cur.execute("""create table test (data int primary key); insert
into test values (1);""")
cnn.commit()
# make an error
try:
cur.execute("""insert into test values (1)""")
except psycopg2.IntegrityError:
# connection created in the handler
cnn2 = psycopg2.connect(dsn)
cur2 = cnn2.cursor()
cur2.execute("""insert into test values (2)""")
# was cnn2 autocommit?
cnn3 = psycopg2.connect(dsn)
cur3 = cnn3.cursor()
cur3.execute("select count(*) from test where data = 2")
n = cur3.fetchone()[0]
assert n == 0, "connection in exception handler autocommit"
# double check
cnn2.commit()
cur3.execute("select count(*) from test where data = 2")
n = cur3.fetchone()[0]
assert n == 1
print "ok"
test("dbname=test")
Ma questo test, nelle mie condizioni passa. Io ho sottomano solo una
versione di sviluppo di psycopg: posso provare più tardi con quella che usi
tu, ma se riesci a creare la condizione che fa fallire l'assert col tuo
setup allora possiamo dire che c'è un bug. Altrimenti non si sa :)
--
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com
Maggiori informazioni sulla lista
Python