Ich habe ein Datenbankschema, das in einer Vielzahl von verschiedenen Datenbank-Engines implementiert werden könnte (sagen wir eine MS Access-Datenbank, die ich mit pyodbc oder einer SQLite-Datenbank verbinden werde Eingebautes sqlite3-Modul als einfaches Beispiel).Catch Python DatabaseErrors generisch
Ich möchte eine Fabrik Funktion/Methode erstellen, die eine Datenbankverbindung des entsprechenden Typs auf einige Parameter, ähnlich der folgenden Basis zurückgibt:
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
Jetzt habe ich eine Abfrage-Code Kapiert sollte mit jedem Verbindungstyp arbeiten (da das Schema unabhängig von dem zugrunde liegenden DB Motor identisch ist), aber eine Ausnahme auslösen kann, die ich zu fangen brauchen werden: ich habe
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...
das Problem ist, dass die Klassen Database von jeder DB API 2.0-Implementierung nicht shar e eine gemeinsame Basisklasse (außer der allzu generischen Ausnahme), weshalb ich nicht weiß, wie man diese Ausnahmen generisch abfängt. Offensichtlich konnte ich etwas tun, wie folgt aus:
try:
# as before
except sqlite3.DatabaseError as err:
# do something
except pyodbc.DatabaseError as err:
# do something again
... wo ich einen expliziten catch-Block für jede mögliche Datenbank-Engine enthalten. Aber das scheint mir nicht pythisch zu sein.
Wie kann ich DatabaseErrors von verschiedenen zugrunde liegenden DB API 2.0-Datenbankimplementierungen generisch abfangen?
Ihre Lösung # 2 hat den Trick gemacht. Es war mir nicht eingefallen, dass außer Aussagen dynamisch waren. Also gebe ich jetzt die verbindungs- und verbindungsspezifische Ausnahmeklasse von der Factory-Funktion zurück und teste den zurückgegebenen Ausnahmetyp in der except-Anweisung. Klappt wunderbar! –