2010-03-30 50 views
6

在mysql-python中使用遊標我曾經調用過「BEGIN;」,「COMMIT;」和「ROLLBACK;」明確如下:爲什麼Python的DB-API中的連接沒有「開始」操作?

try: 
    cursor.execute("BEGIN;") 
    # some statements 
    cursor.execute("COMMIT;") 
except: 
    cursor.execute("ROLLBACK;") 

然後,我發現,底層連接對象具有相應的方法:

try: 
    cursor.connection.begin() 
    # some statements 
    cursor.connection.commit() 
except: 
    cursor.connection.rollback() 

檢查的DB-API PEP我發現它沒有提到的begin()方法連接對象,即使是擴展。

順便說一句,當您使用該方法時,Mysql-python會拋出DeprecationWarning。例如,sqlite3.connection根本沒有這個方法。

問題是爲什麼PEP中沒有這樣的方法?這個語句是不是可選的,是否足以調用commit()呢?

回答

3

決定回答自己:

在python-list中的thread about DB API 2.0 transactions從引人注目的書SQL The Complete Reference以下摘錄讓我覺得DB API實現SQL1標準行爲:

的第一個版本SQL標準 (SQL1)根據DB2早期版本中的事務 支持定義了隱式事務 模式。 在隱式模式下,僅支持COMMIT和 ROLLBACK語句。甲 SQL事務自動開始 與第一SQL語句由用戶或程序執行 並且當 COMMIT或執行ROLLBACK結束。一筆交易的 結尾暗含 開始一筆交易。

當RDBSM支持自動提交模式並且當前連接處於該模式時,顯式事務模式(SQL2和SQL:1999)似乎很方便,但DB API並不反映它。

7

看起來a this previously asked question。通常用於交易的「協議」是:

cursor = conn.cursor() 
try: 
    cursor.execute(...) 
except DatabaseError: 
    conn.rollback() 
    raise 
else: 
    conn.commit() 
finally: 
    cursor.close() 

從python 2.6開始sqlite Connection objects can be used as context managers that automatically commit or rollback transactions

+0

感謝您對鄰居問題的有用鏈接。這不是我的問題的答案,但它可以闡明可能的原因。 – newtover 2010-03-31 07:56:29

+0

@newtower:你是對的,我有疑問回答或只是發表評論,但這樣做,我可以張貼小剪輯。 – 2010-03-31 11:21:22

+0

順便說一下,雖然用上下文管理器包裝連接是有用的,但我更願意在相鄰查詢中重新使用連接,但即使在Python 2.6中,遊標類也不會實現上下文管理器接口。 – newtover 2010-04-01 09:40:58

相關問題