[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