开发者

python sqlite 3 : roll back to save point fails

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"

In above code snippet , It says "roll back to save point failed". What went wrong?

EDIT: I changed the code as shown below and getting error messages

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

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

error

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.Operatio开发者_StackOverflownalError: no such savepoint: pt


Don't ever catch exceptions you aren't handling. Let it raise, so you can have useful error messages and tracebacks.

Example:

>>> c.execute('rollback to savepoint pt;')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
sqlite3.OperationalError: no such savepoint: pt

From the traceback I can know the error is that there's no pt savepoint. I can't know what's wrong with yours because you're hiding the very information that can help you most. Catching all errors and printing some "Failed" message is dumb - the traceback is much more useful and explains the problem better.


EDIT: Your code wasn't exactly a easy-to-run testcase, but by reading it I was able to write some code myself to reproduce the issue. I can't explain exactly what is going on yet, but I found a way to make it work - related to how sqlite3 module deals with transactions.

Here's my full, runnable example:

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)

The line that makes it work is db.isolation_level = None. If you comment it out, it breaks just like your error. I've tried using all the documented values “DEFERRED”, “IMMEDIATE” and “EXCLUSIVE”, all ended in error.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜