2010-02-02 128 views
1
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" 

在上面的代碼片段中,它說「回退到保存點失敗」。 出了什麼問題?python sqlite 3:回滾保存點失敗

編輯: 我改變了代碼如下圖所示,收到錯誤消息

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 
+0

什麼是例外? – 2010-02-02 08:18:54

+0

永遠不會捕獲你沒有處理的異常。讓它升起,這樣你可以得到有用的錯誤信息和回溯。 – nosklo 2010-02-02 08:42:47

+0

obj1.rollback_savepoint() 文件 「open_db.py」,第65行,在rollback_savepoint self.db.execute( 「回滾到保存點PT;」) sqlite3.OperationalError:沒有這樣的保存點:PT – 2010-02-02 09:02:20

回答

4

千萬不要趕你不處理異常。讓它升起,這樣你可以得到有用的錯誤信息和回溯。

例子:

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

從回溯我可以知道錯誤是沒有pt保存點。我不知道你的問題,因爲你隱藏了最能幫助你的信息。捕捉所有錯誤並打印一些「失敗」信息是愚蠢的 - 回溯更有用,並更好地解釋問題。


編輯: 您的代碼是不完全是一個易於運行測試用例,但通過閱讀它,我能自己編寫一些代碼來重現問題。我無法解釋究竟發生了什麼,但我找到了一種方法使其工作 - 與how sqlite3 module deals with transactions有關。

這裏是我的全部,可運行的例子:

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。如果你評論它,它就像你的錯誤一樣。我試過使用所有記錄的值「延遲」,「即時」和「獨佔」,都以錯誤結束。

+0

謝謝,消除異常處理後,我得到這個 sqlite3.OperationalError:沒有這樣的保存點:pt 如何打印錯誤,而使用異常處理程序?像python的perror()可用嗎? – 2010-02-02 09:02:03

+0

是的,有 - 但爲什麼?錯誤已經自動打印出來,只是爲了打印而複製代碼 – nosklo 2010-02-03 10:51:54

+0

好吧。您是否看到上面的錯誤消息這裏有什麼問題?保存點工作正常,回滾產生錯誤信息。 – 2010-02-04 06:59:49