Domanda Python / SQLite3: impossibile eseguire il commit: nessuna transazione è attiva


Sto provando a codificare a indicizzatore del libro usando Python (tradizionale, 2.7) e SQLite (3).

Il codice si riduce a questa sequenza di istruzioni SQL:

'select count(*) from tag_dict' ()
/* [(30,)] */
'select count(*) from file_meta' ()
/* [(63613,)] */
'begin transaction' ()
'select id from archive where name=?' ('158326-158457.zip',)
/* [(20,)] */
'select id from file where name=? and archive=?' ('158328.fb2', 20)
/* [(122707,)] */
'delete from file_meta where file=?' (122707,)
'commit transaction' ()
# error: cannot commit - no transaction is active

Il livello di isolamento è 'DEFERRED' ('ESCLUSIVO' non è migliore).

Ho tentato di utilizzare connection.commit () invece di cursor.execute ('commit') - non è successo nulla di utile.

  • Certo, ho cercato lo stackoverflow e la rete, ma le risposte trovate sono irrilevanti.
  • autocommit la modalità è inaccettabile per ragioni di prestazione.
  • Io uso l'unico file di database alla volta.
  • Il mio codice viene eseguito in thread singolo.
  • Tutta l'esecuzione SQL viene eseguita tramite una singola funzione che garantisce che non ne abbia più di solo uno cursore aperto alla volta.

Quindi, cosa c'è di sbagliato con la transazione qui?

Se uso connection.commit () (nota: non c'è alcun metodo connection.begin!), Quindi mi limito a perdere i miei dati.

Certo, ho permesso di duplicare / triplicare i permessi dei file controllati sul file di database e sulla sua directory.


Bene, come spesso accade ho trovato la soluzione solo un minuto dopo aver posto la domanda.

Come novizio, non posso rispondere alla mia domanda per 8 ore ... Quindi, l'anwer è ora lì:

La soluzione era trovato qui e consiste nell'unica idea:

Non utilizzare mai BEGIN / COMMIT in modalità non autocommit nell'applicazione Python - usa solo db.commit () e db.rollback ()!

Sembra strano, ma funziona.


15
2018-03-19 15:41


origine


risposte:


Bene, come spesso accade ho trovato la soluzione solo un minuto dopo aver posto la domanda.

La soluzione era trovato qui e consiste nell'unica idea:

Non utilizzare mai BEGIN / COMMIT in modalità non di autocommit nell'applicazione Python - usa solo db.commit () e db.rollback ()!

Sembra strano, ma funziona.


11
2018-03-20 05:44



Questa è una risposta piuttosto tardiva, ma forse date un'occhiata a APSW se volete un controllo più preciso sulle transazioni. Ho eseguito alcuni test sulle transazioni posticipate che coinvolgono le letture su pysqlite e non sembra funzionare correttamente.

https://code.google.com/p/apsw/


3
2017-08-27 18:33



cursor=connection.cursor()
cursor.executemany("insert into person(firstname, lastname) values (?, ?)", persons)
connection.commit()

0
2017-12-10 23:04