]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [feature] New session events after_transaction_create
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 20 Sep 2012 22:39:27 +0000 (18:39 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 20 Sep 2012 22:39:27 +0000 (18:39 -0400)
    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.

CHANGES
lib/sqlalchemy/orm/events.py
lib/sqlalchemy/orm/session.py
test/orm/test_events.py

diff --git a/CHANGES b/CHANGES
index 5ac1b4d34723e3eb2b914317c828fe0fe7249cb6..f8991bd0382a219b73fa14fc1364f92eb080149d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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"
index 67f6d64313bd2c1367737ccf43d2b6cc497b16c5..61517770f8682b0d0f12daec4fd758ef5215ff43 100644 (file)
@@ -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.
 
index e0f79cd8a5fbcd6960615ab5380a9172aad3e3ea..36ff5fc84e81a7b5fda3cd1c70c5a65cd52b9d9f 100644 (file)
@@ -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
 
index bf413125acd22f75c7200052503c672fad6d245f..e49a4a6a7aebc42159b953fd6a5eb877e8da6c58 100644 (file)
@@ -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