2016-10-22 23 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语句中测试返回的异常类型。奇迹般有效! –