Add _wrap_db_error() support to SessionTransaction.commit()

This patch adds _wrap_db_error() to the commit()
and rollback() methods of sqlalchemy.orm.session.SessionTransaction,
which is the object that is dealt with when one invokes
code of the form "with session.begin():".  The context manager
form does not invoke the commit() method on the
SQLAlchemy Session directly, and instead calls the one
local to the SessionTransaction.

In order to intercept this, we must build a subclass
of SessionTransaction with the appropriate wrapping, and
then patch it into the object that is returned by
Session.begin(), ensuring that it is compatible with
_wrap_db_error().

This whole approach is legacy; newer oslo.db versions
intercept errors at the point at which they occur
via engine events.

Tests are omitted here as we are relying upon the tests
that were added to the corresponding oslo-incubator code.

Closes-bug: #1370191

Change-Id: Ie0456e6daa86c99cf6fbe56ca5dfd8a618f14232
This commit is contained in:
Mike Bayer 2014-09-26 17:27:53 -04:00
parent 3371ad81ba
commit cac6472fd2
1 changed files with 19 additions and 0 deletions

View File

@ -700,6 +700,25 @@ class Session(sqlalchemy.orm.session.Session):
def commit(self, *args, **kwargs):
return super(Session, self).commit(*args, **kwargs)
def begin(self, **kw):
trans = super(Session, self).begin(**kw)
trans.__class__ = SessionTransactionWrapper
return trans
class SessionTransactionWrapper(sqlalchemy.orm.session.SessionTransaction):
@property
def bind(self):
return self.session.bind
@_wrap_db_error
def commit(self, *args, **kwargs):
return super(SessionTransactionWrapper, self).commit(*args, **kwargs)
@_wrap_db_error
def rollback(self, *args, **kwargs):
return super(SessionTransactionWrapper, self).rollback(*args, **kwargs)
def get_maker(engine, autocommit=True, expire_on_commit=False):
"""Return a SQLAlchemy sessionmaker using the given engine."""