diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-09-20 18:39:27 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-09-20 18:39:27 -0400 |
commit | 248cf4c5d2f227c7cc49772f023807aebeb5c969 (patch) | |
tree | 1305b8a8db9203093d9ddf9e26f0bc5bc7a26cf1 | |
parent | e5accce97bae1b35eeb1eb26f8281a98c58d2cef (diff) | |
download | sqlalchemy-248cf4c5d2f227c7cc49772f023807aebeb5c969.tar.gz |
- [feature] New session events after_transaction_create
and after_transaction_end
allows tracking of new SessionTransaction objects.
If the object is inspected, can be used to determine
when a session first becomes active and when
it deactivates.
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/events.py | 20 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/session.py | 10 | ||||
-rw-r--r-- | test/orm/test_events.py | 40 |
4 files changed, 64 insertions, 13 deletions
@@ -153,6 +153,13 @@ underneath "0.7.xx". PG's DELETE..USING is also not available in Core yet. + - [feature] New session events after_transaction_create + and after_transaction_end + allows tracking of new SessionTransaction objects. + If the object is inspected, can be used to determine + when a session first becomes active and when + it deactivates. + - [bug] Improvements to joined/subquery eager loading dealing with chains of subclass entities sharing a common base, with no specific "join depth" diff --git a/lib/sqlalchemy/orm/events.py b/lib/sqlalchemy/orm/events.py index 67f6d6431..61517770f 100644 --- a/lib/sqlalchemy/orm/events.py +++ b/lib/sqlalchemy/orm/events.py @@ -955,6 +955,26 @@ class SessionEvents(event.Events): def _remove(cls, identifier, target, fn): raise NotImplementedError("Removal of session events not yet implemented") + def after_transaction_create(self, session, transaction): + """Execute when a new :class:`.SessionTransaction` is created. + + :param session: the target :class:.`Session`. + :param transaction: the target :class:`.SessionTransaction`. + + .. versionadded:: 0.8 + + """ + + def after_transaction_end(self, session, transaction): + """Execute when the span of a :class:`.SessionTransaction` ends. + + :param session: the target :class:.`Session`. + :param transaction: the target :class:`.SessionTransaction`. + + .. versionadded:: 0.8 + + """ + def before_commit(self, session): """Execute before commit is called. diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index e0f79cd8a..36ff5fc84 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -150,6 +150,9 @@ class SessionTransaction(object): if self.session._enable_transaction_accounting: self._take_snapshot() + if self.session.dispatch.after_transaction_create: + self.session.dispatch.after_transaction_create(self.session, self) + @property def is_active(self): return self.session is not None and self._active @@ -379,9 +382,14 @@ class SessionTransaction(object): connection.close() else: transaction.close() + + self._deactivate() + if self.session.dispatch.after_transaction_end: + self.session.dispatch.after_transaction_end(self.session, self) + + if self._parent is None: if not self.session.autocommit: self.session.begin() - self._deactivate() self.session = None self._connections = None diff --git a/test/orm/test_events.py b/test/orm/test_events.py index bf413125a..e49a4a6a7 100644 --- a/test/orm/test_events.py +++ b/test/orm/test_events.py @@ -545,6 +545,8 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): sess = Session(**kw) for evt in [ + 'after_transaction_create', + 'after_transaction_end', 'before_commit', 'after_commit', 'after_rollback', @@ -576,9 +578,10 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): sess.flush() eq_( canary, - [ 'before_attach', 'after_attach', 'before_flush', 'after_begin', + [ 'before_attach', 'after_attach', 'before_flush', + 'after_transaction_create', 'after_begin', 'after_flush', 'after_flush_postexec', - 'before_commit', 'after_commit',] + 'before_commit', 'after_commit','after_transaction_end'] ) def test_rollback_hook(self): @@ -597,11 +600,17 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): sess.commit ) sess.rollback() - eq_(canary, ['before_attach', 'after_attach', 'before_commit', 'before_flush', - 'after_begin', 'after_flush', 'after_flush_postexec', - 'after_commit', 'before_attach', 'after_attach', 'before_commit', - 'before_flush', 'after_begin', 'after_rollback', - 'after_soft_rollback', 'after_soft_rollback']) + eq_(canary, + + ['before_attach', 'after_attach', 'before_commit', 'before_flush', + 'after_transaction_create', 'after_begin', 'after_flush', + 'after_flush_postexec', 'after_transaction_end', 'after_commit', + 'after_transaction_end', 'after_transaction_create', + 'before_attach', 'after_attach', 'before_commit', + 'before_flush', 'after_transaction_create', 'after_begin', 'after_rollback', + 'after_transaction_end', + 'after_soft_rollback', 'after_transaction_end','after_transaction_create', + 'after_soft_rollback']) def test_can_use_session_in_outer_rollback_hook(self): User, users = self.classes.User, self.tables.users @@ -640,8 +649,10 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): u = User(name='u1') sess.add(u) sess.flush() - eq_(canary, ['before_attach', 'after_attach', 'before_flush', 'after_begin', - 'after_flush', 'after_flush_postexec']) + eq_(canary, ['before_attach', 'after_attach', 'before_flush', + 'after_transaction_create', 'after_begin', + 'after_flush', 'after_flush_postexec', + 'after_transaction_end']) def test_flush_in_commit_hook(self): User, users = self.classes.User, self.tables.users @@ -656,8 +667,11 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): u.name = 'ed' sess.commit() - eq_(canary, ['before_commit', 'before_flush', 'after_flush', - 'after_flush_postexec', 'after_commit']) + eq_(canary, ['before_commit', 'before_flush', 'after_transaction_create', 'after_flush', + 'after_flush_postexec', + 'after_transaction_end', + 'after_commit', + 'after_transaction_end', 'after_transaction_create',]) def test_state_before_attach(self): User, users = self.classes.User, self.tables.users @@ -700,7 +714,9 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): def test_standalone_on_commit_hook(self): sess, canary = self._listener_fixture() sess.commit() - eq_(canary, ['before_commit', 'after_commit']) + eq_(canary, ['before_commit', 'after_commit', + 'after_transaction_end', + 'after_transaction_create']) def test_on_bulk_update_hook(self): User, users = self.classes.User, self.tables.users |