2016-10-22 25 views
1

我有一個數據庫模式,可能會在各種不同的數據庫引擎中實現(比方說我將連接到pyodbc或SQLite數據庫的MS Access數據庫,我將通過內置的sqlite3模塊就是一個簡單的例子)。一般捕獲python DatabaseErrors

我想創建一個工廠函數/方法返回一個基於某些參數的適當類型的數據庫連接,類似以下內容:

def createConnection(connType, params): 
    if connType == 'sqlite': 
     return sqlite3.connect(params['filename']) 
    elif connType == 'msaccess': 
     return pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ={};'.format(params['filename'])) 
    else: 
     # do something else 

現在我已經得到了一些查詢代碼應該與任何連接類型工作(因爲該架構是相同的,不管底層的數據庫引擎),但可能會扔東西,我需要捕捉異常:

db = createDatabase(params['dbType'], params) 

cursor = db.cursor() 

try: 
    cursor.execute('SELECT A, B, C FROM TABLE') 
    for row in cursor: 
     print('{},{},{}'.format(row.A, row.B, row.C)) 

except DatabaseError as err: 
    # Do something... 

我遇到的問題是,DatabaseError類從每個DB API 2.0實現不要shar e是一個通用的基類(除了泛型異常之外),所以我不知道如何一般地捕捉這些異常。很明顯,我可以做類似以下的事情:

try: 
    # as before 
except sqlite3.DatabaseError as err: 
    # do something 
except pyodbc.DatabaseError as err: 
    # do something again 

...其中我包括一個明確的catch塊爲每個可能的數據庫引擎。但是這對我來說似乎是非pythonic。

如何從一般底層數據庫API 2.0數據庫實現中一般捕獲DatabaseErrors?

回答

1

有許多方法:

  1. 使用捕獲所有異常,然後制定出它是什麼例外。如果它不在您的列表中,請再次提出異常(或您自己的異常)。請參閱:Python When I catch an exception, how do I get the type, file, and line number?

  2. 也許您想以不同的方式解決問題:您的工廠代碼還應該提供要測試的異常。

  3. 在我看來(以及我在實際中使用的)中,一個更簡單的方法是爲所有數據庫連接創建一個類,併爲每個特定的數據庫類型/語法創建子類。繼承可以讓你照顧到所有的特性。出於某種原因,我從來不必擔心這個問題。

+0

你的解決方案#2做到了。我沒有想到,除了陳述是動態的。因此,現在我從工廠函數返回連接和特定於連接的異常類,並在except語句中測試返回的異常類型。奇蹟般有效! –