2010-03-30 7 views
6

Utilizzo dei cursori in mysql-python Ero solito chiamare "BEGIN;", "COMMIT;" e "ROLLBACK;" esplicitamente come segue:Perché la connessione in DB-API Python non ha l'operazione "inizio"?

try: 
    cursor.execute("BEGIN;") 
    # some statements 
    cursor.execute("COMMIT;") 
except: 
    cursor.execute("ROLLBACK;") 

poi, ho scoperto che l'oggetto connessione sottostante ha i metodi corrispondenti:

try: 
    cursor.connection.begin() 
    # some statements 
    cursor.connection.commit() 
except: 
    cursor.connection.rollback() 

ispezionare il DB-API PEP ho scoperto che non menziona il metodo begin() per l'oggetto di connessione, anche per le estensioni.

Mysql-python, a proposito, lancia il deprecazione, quando si utilizza il metodo. sqlite3.connection, ad esempio, non ha affatto il metodo.

E la domanda è perché non esiste un tale metodo nel PEP? L'istruzione è in qualche modo facoltativa, è sufficiente richiamare commit()?

risposta

3

deciso di rispondere me stesso:

Un thread about DB API 2.0 transactions in python-list e il seguente estratto dal libro evidente SQL The Complete Reference mi fanno pensare che DB API implementa SQL1 comportamento standard:

La prima versione del Lo standard SQL (SQL1) ha definito una modalità implicita della transazione , in base al supporto della transazione nelle prime versioni di DB2. In modalità implicita, solo le istruzioni COMMIT e ROLLBACK sono supportate. Una transazione SQL inizia automaticamente con la prima istruzione SQL eseguita da un utente o da un programma e termina quando viene eseguito un COMMIT o un ROLLBACK . La fine di una transazione implicitamente avvia una nuova.

modalità di transazione esplicita (lo SQL2 e SQL: 1999) sembra essere a portata di mano quando il RDBSM supporta la modalità autocommit e la connessione corrente è in tale modalità, ma DB API semplicemente non riflette esso.

7

look a this previously asked question. Generalmente il "protocollo" da utilizzare con le transazioni è:

cursor = conn.cursor() 
try: 
    cursor.execute(...) 
except DatabaseError: 
    conn.rollback() 
    raise 
else: 
    conn.commit() 
finally: 
    cursor.close() 

A partire da Python 2.6 sqlite Connection objects can be used as context managers that automatically commit or rollback transactions.

+0

Grazie per il link utile alla domanda adiacente. Questa non è la risposta alla mia domanda, ma fa luce sulle possibili ragioni. – newtover

+0

@newtower: hai ragione, ero in dubbio per rispondere o semplicemente postare un commento ma facendo così potrei postare quel piccolo snip. –

+0

A proposito, sebbene sia utile includere la connessione con un gestore di contesto, preferisco riutilizzare la connessione nelle query adiacenti, ma le classi di cursori non implementano l'interfaccia contextmanager, anche in python 2.6. – newtover