[DB-SIG] Experiences with DB-API2.0

Kevin Jacobs jacobs@penguin.theopalgroup.com
Thu, 20 Jun 2002 10:05:06 -0400 (EDT)


On 20 Jun 2002, Andy Dustman wrote:
> Would the solution be to have a standard DBException module which
> defines these exceptions? These exceptions would need to be imported
> into each database module (though not exported); I doubt they will ever
> be "standard" exceptions (in the exceptions module). Since usually these
> exceptions are raised in C code, that would require some implementation
> work, although _mysql (the C portion of MySQLdb) already imports it's
> exceptions from a separate module (_mysql_exceptions).

That is one solution -- probably the optimal solution.  In the mean time we
create a set of "virtualized" exceptions are patched into all the active
drivers.  This is how we do it:

  # Define our own virtual exception names and classes

  dbapi_exceptions = [ 'Warning',
                       'Error',
                       'InterfaceError',
                       'DatabaseError',
                       'DataError',
                       'OperationalError',
                       'IntegrityError',
                       'InternalError',
                       'ProgrammingError',
                       'NotSupportedError' ]

  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

  def _virtualize_exceptions(module):
    for e in dbapi_exceptions:
      driver_exception = getattr(module, e)
      global_exception = globals()[e]
      driver_exception.__bases__ += (global_exception,)

  _virtualize_exceptions(MySQLdb)
  _virtualize_exceptions(MSSQL)
  _virtualize_exceptions(PgSQL)
  _virtualize_exceptions(PoPy)
  _virtualize_exceptions(psycopg)
  # ... etc ...

Of course, this approach relies on being able to change base classes of the
module exceptions.  Some extra work will be needed make this work when
DB-API drivers start to use new-style classes for exceptions.

-Kevin

--
Kevin Jacobs
The OPAL Group - Enterprise Systems Architect
Voice: (216) 986-0710 x 19         E-mail: jacobs@theopalgroup.com
Fax:   (216) 986-0714              WWW:    http://www.theopalgroup.com