Никогда не поймайте исключения, которые вы не обрабатываете. Позвольте этому подняться, чтобы вы могли иметь полезные сообщения об ошибках и трассировки.
Пример:
>>> c.execute('rollback to savepoint pt;')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
sqlite3.OperationalError: no such savepoint: pt
Из трассировки я могу знать, что ошибка в том, что нет pt
точки сохранения. Я не могу знать, что с тобой не так, потому что ты скрываешь ту информацию, которая может тебе помочь больше всего. Перехватывать все ошибки и печатать некоторые сообщения «Failed» - глупость - трассировка намного полезнее и лучше объясняет проблему.
EDIT:
Ваш код не был простым в использовании тестовым сценарием, но, прочитав его, я смог сам написать некоторый код, чтобы воспроизвести проблему. Я пока не могу точно объяснить, что происходит, но я нашел способ заставить это работать - связано с , как модуль sqlite3 обрабатывает транзакции .
Вот мой полный, работающий пример:
import sqlite3
from tempfile import NamedTemporaryFile as NF
import os
f = NF(suffix='.db', delete=False).name
db = sqlite3.connect(f)
try:
db.execute('CREATE TABLE foo (id INTEGER PRIMARY KEY, data VARCHAR)')
db.isolation_level = None
db.execute('INSERT INTO foo (data) values (?)', ('hello',))
db.execute('INSERT INTO foo (data) values (?)', ('world',))
db.execute("savepoint pt;")
db.execute('INSERT INTO foo (data) values (?)', ('bah',))
db.execute('INSERT INTO foo (data) values (?)', ('goodbye world',))
db.execute("rollback to savepoint pt;")
db.execute('INSERT INTO foo (data) values (?)', ('peace',))
assert list(db.execute('select * from foo')) == [(1, 'hello'),
(2, 'world'),
(3, 'peace')]
finally:
db.close()
os.remove(f)
Строка, которая заставляет его работать, - db.isolation_level = None
. Если вы закомментируете это, оно сломается так же, как ваша ошибка. Я попытался использовать все задокументированные значения «DEFERRED», «IMMEDIATE» и «EXCLUSIVE», все закончилось ошибкой.