[DB-SIG] (Database Abstraction Layer) Wrapping DBAPI Exceptions
Peter L. Buschman
plblists at iotk.com
Fri Sep 26 14:59:02 EDT 2003
Kevin:
That is awesome. It took me a little while to understand how your code
example worked, but that is
definitely a better approach than what I was thinking of and the effect is
exactly what I am aiming for.
Thank you. You can be sure that you and everyone else will be mentioned in
the credits for answering
my newbie questions :)
Cheers!
--PLB
At 07:31 AM 9/26/2003 -0400, Kevin Jacobs wrote:
>On Fri, 26 Sep 2003, Peter L. Buschman wrote:
> > The next thing I want to do is wrap the DPABI exceptions of the underlying
> > driver and raise my own equivalents ( which will handle
> > exception arguments consistently... ) whenever they occur. Here is the
> > strategy that comes to mind, but I am wondering how the rest of you might
> > handle a case like this?
>
>My DB-API abstraction layer virtualizes exceptions by patching the base
>classes of the driver exception classes:
>
>abstract.py:
>
> class Warning (StandardError) : pass
> class Error (StandardError) : pass
> class InterfaceError (Error) : pass
> class DatabaseError (Error) : pass
> class DataError (DatabaseError) : pass
> class OperationalError (DatabaseError) : pass
> class IntegrityError (DatabaseError) : pass
> class InternalError (DatabaseError) : pass
> class ProgrammingError (DatabaseError) : pass
> class NotSupportedError (DatabaseError) : pass
>
> dbapi_exceptions = [ 'Warning',
> 'Error',
> 'InterfaceError',
> 'DatabaseError',
> 'DataError',
> 'OperationalError',
> 'IntegrityError',
> 'InternalError',
> 'ProgrammingError',
> 'NotSupportedError' ]
>
> def __import_exceptions(module):
> for e in dbapi_exceptions:
> sub_exception = getattr(module, e)
> abstract_exception = globals()[e]
> sub_exception.__bases__ += (abstract_exception,)
>
>Whenever I import a native DB-API driver, I call __import_exceptions, e.g.:
>
> import psycopg, MySQLdb, Sybase, PoPy, pgdb, MSSQL # ...
> from pyPgSQL import PgSQL
>
> __import_exceptions(psycopg)
> __import_exceptions(MySQLdb)
> __import_exceptions(Sybase)
> __import_exceptions(PoPy)
> __import_exceptions(pgdb)
> __import_exceptions(MSSQL)
> __import_exceptions(PgSQL)
>
>Now I can catch any DB-API exception from the above modules without knowing
>which one generated it.
>
> def query(dbcon, sql):
> cursor = dbcon.cursor()
> cursor.execute(sql)
> return cursor.fetchall()
>
> def get_accounts(dbcon):
> try:
> return query(dbcon, 'SELECT ACCOUNTID FROM ACCOUNTS;')
> except abstract.ProgrammingError:
> # Do not trap errors due to bad SQL
> raise
> except abstract.DatabaseError:
> # All other database related errors return empty results
> return []
>
>Clearly, this example is a little contrived, but it gets the point across.
>The above routines do not need to know which underlying driver they are
>connected to to be able to catch exceptions. Of course, there are a
>thousand _other_ things that are not abstracted in this example.
>
>Feel free to reuse the above idea. Just mention me in the credits
>somewhere. ;)
>
>-Kevin
>
>
>--
>--
>Kevin Jacobs
>The OPAL Group - Enterprise Systems Architect
>Voice: (440) 871-6725 x 19 E-mail: jacobs at theopalgroup.com
>Fax: (440) 871-6722 WWW: http://www.theopalgroup.com/
More information about the DB-SIG
mailing list