[PATCH 3.26] Account for new psycopg2 exception classes mapping

Denis Laxalde denis.laxalde at logilab.fr
Thu May 2 13:23:02 CEST 2019


Denis Laxalde a écrit :
> Denis Laxalde a écrit :
> > # HG changeset patch
> > # User Denis Laxalde <denis.laxalde at logilab.fr>
> > # Date 1554715493 -7200
> > #      Mon Apr 08 11:24:53 2019 +0200
> > # Branch 3.26
> > # Node ID 6aa06cf007ded624a13a76158cfc5b52321363ea
> > # Parent  8ef162b039a01a8e244f5e0e96e09a177ce396e1
> > # Available At https://hg.logilab.org/review/cubicweb
> > #              hg pull https://hg.logilab.org/review/cubicweb -r 6aa06cf007de
> > Account for new psycopg2 exception classes mapping
> 
> Up.

Up, Up.

> > From psycopg2 >= 2.8, specific exceptions are raised corresponding to
> > postgresql errors. E.g. a CheckViolation exception is raised instead of
> > a generic IntegrityError previously when a constraint violation occurs.
> > The way we intercept database errors, especially for constraint
> > violation, is not compliant with that because we do not catch subclasses
> > of IntegrityError in native source's doexec() method.
> > 
> > We fix this by checking for the presence of IntegrityError error in
> > exception class's mro. This is still overcomplicated and clumsy, because
> > we still use string comparison, but this is the best we can do as far as
> > I know. (A better fix would be 'isinstance(ex, IntegrityError)' but we
> > have no engine-independent error classes, so this is not possible.
> > Something like sqlalchemy's DBAPI Errors [1] might help:
> > https://docs.sqlalchemy.org/en/latest/errors.html#dbapi-errors)
> > 
> > diff --git a/cubicweb/server/sources/native.py b/cubicweb/server/sources/native.py
> > --- a/cubicweb/server/sources/native.py
> > +++ b/cubicweb/server/sources/native.py
> > @@ -695,7 +695,8 @@ class NativeSQLSource(SQLAdapterMixIn, A
> >                          self.debug('transaction has been rolled back')
> >                  except Exception:
> >                      pass
> > -            if ex.__class__.__name__ == 'IntegrityError':
> > +            if any(cls.__name__ for cls in ex.__class__.__mro__
> > +                   if cls.__name__ == 'IntegrityError'):
> >                  # need string comparison because of various backends
> >                  for arg in ex.args:
> >                      # postgres, sqlserver



More information about the cubicweb-devel mailing list