python sqlite 3: откат к точке сохранения не удался - PullRequest
1 голос
/ 02 февраля 2010
def rollback_savepoint(self):
    try:
        self.db.execute("rollback to savepoint pt;")
    except:
        print "roll back to save point failed"
    else:
        print "Roll back to save point. Done"

В приведенном выше фрагменте кода написано: «Откат к точке сохранения не выполнен».Что пошло не так?

РЕДАКТИРОВАТЬ: я изменил код, как показано ниже, и получаю сообщения об ошибках

self.db.execute("savepoint pt;")
print "Save point created"

self.cursor.execute("insert into STK values(33)")
self.db.execute("rollback to savepoint pt;")

ошибка

Save point created
Traceback (most recent call last):
  File "open_db.py", line 77, in <module>
    obj1.save_point()
  File "open_db.py", line 63, in save_point
    self.db.execute("rollback to savepoint pt;")
sqlite3.OperationalError: no such savepoint: pt

1 Ответ

4 голосов
/ 02 февраля 2010

Никогда не поймайте исключения, которые вы не обрабатываете. Позвольте этому подняться, чтобы вы могли иметь полезные сообщения об ошибках и трассировки.

Пример:

>>> 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», все закончилось ошибкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...