У меня есть схема базы данных, которая может быть реализована в различных механизмах баз данных (скажем, база данных MS Access, к которой я подключусь с помощью pyodbc, или база данных SQLite, к которой я подключусь через встроенный модуль sqlite3 в качестве простой пример).
Я хотел бы создать фабричную функцию / метод, который возвращает соединение с базой данных соответствующего типа на основе некоторого параметра, как показано ниже:
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 не имеют общего базового класса (кроме слишком общего исключения), поэтому я не знаю, как в общем случае отлавливать эти исключения. Очевидно, я мог бы сделать что-то вроде следующего:
try:
# as before
except sqlite3.DatabaseError as err:
# do something
except pyodbc.DatabaseError as err:
# do something again
... где я включил явный блок catch для каждого возможного движка базы данных. Но мне это кажется явно непифоническим.
Как я могу в общем перехватить DatabaseErrors из различных базовых реализаций базы данных DB API 2.0?