]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- The :meth:`.ConnectionEvents.after_cursor_execute` event is now
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 19 Mar 2014 17:03:44 +0000 (13:03 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 19 Mar 2014 17:03:44 +0000 (13:03 -0400)
emitted for the "_cursor_execute()" method of :class:`.Connection`;
this is the "quick" executor that is used for things like
when a sequence is executed ahead of an INSERT statement, as well as
for dialect startup checks like unicode returns, charset, etc.
the :meth:`.ConnectionEvents.before_cursor_execute` event was already
invoked here.  The "executemany" flag is now always set to False
here, as this event always corresponds to a single execution.
Previously the flag could be True if we were acting on behalf of
an executemany INSERT statement.

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/engine/base.py
test/engine/test_execute.py

index 87606c8d83ad1351299481e75e618fb61eb3770c..dcec53d1e0beb4f7100ef3decccda3bf1d7c32a8 100644 (file)
 .. changelog::
     :version: 0.9.4
 
+    .. change::
+        :tags: bug, engine
+
+        The :meth:`.ConnectionEvents.after_cursor_execute` event is now
+        emitted for the "_cursor_execute()" method of :class:`.Connection`;
+        this is the "quick" executor that is used for things like
+        when a sequence is executed ahead of an INSERT statement, as well as
+        for dialect startup checks like unicode returns, charset, etc.
+        the :meth:`.ConnectionEvents.before_cursor_execute` event was already
+        invoked here.  The "executemany" flag is now always set to False
+        here, as this event always corresponds to a single execution.
+        Previously the flag could be True if we were acting on behalf of
+        an executemany INSERT statement.
+
     .. change::
         :tags: bug, orm
 
index 888a15feea3d9e91ef350a7b466137099b0e0aeb..d3024640bb44575d5d668072db19e03db18d2b3a 100644 (file)
@@ -986,8 +986,7 @@ class Connection(Connectable):
                 statement, parameters = \
                             fn(self, cursor, statement, parameters,
                                         context,
-                                        context.executemany
-                                           if context is not None else False)
+                                        False)
 
         if self._echo:
             self.engine.logger.info(statement)
@@ -996,14 +995,22 @@ class Connection(Connectable):
             self.dialect.do_execute(
                                 cursor,
                                 statement,
-                                parameters)
+                                parameters,
+                                context)
         except Exception as e:
             self._handle_dbapi_exception(
                                 e,
                                 statement,
                                 parameters,
                                 cursor,
-                                None)
+                                context)
+
+        if self._has_events:
+            self.dispatch.after_cursor_execute(self, cursor,
+                                                statement,
+                                                parameters,
+                                                context,
+                                                False)
 
     def _safe_close_cursor(self, cursor):
         """Close the given cursor, catching exceptions
index d3bd3c2cdaeda03c4800128b99a366d294c72218..6efcdcb89ca9ea82becc273f228a075309e4163f 100644 (file)
@@ -1235,6 +1235,48 @@ class EngineEventsTest(fixtures.TestBase):
         canary.be1.assert_call_count(2)
         canary.be2.assert_call_count(2)
 
+    def test_cursor_events_ctx_execute_scalar(self):
+        canary = Mock()
+        e1 = testing_engine(config.db_url)
+
+        event.listen(e1, "before_cursor_execute", canary.bce)
+        event.listen(e1, "after_cursor_execute", canary.ace)
+
+        stmt = str(select([1]).compile(dialect=e1.dialect))
+
+        with e1.connect() as conn:
+            dialect = conn.dialect
+
+            ctx = dialect.execution_ctx_cls._init_statement(
+                            dialect, conn, conn.connection, stmt, {})
+
+            ctx._execute_scalar(stmt, Integer())
+
+        eq_(canary.bce.mock_calls,
+                [call(conn, ctx.cursor, stmt, ctx.parameters[0], ctx, False)])
+        eq_(canary.ace.mock_calls,
+                [call(conn, ctx.cursor, stmt, ctx.parameters[0], ctx, False)])
+
+    def test_cursor_events_execute(self):
+        canary = Mock()
+        e1 = testing_engine(config.db_url)
+
+        event.listen(e1, "before_cursor_execute", canary.bce)
+        event.listen(e1, "after_cursor_execute", canary.ace)
+
+        stmt = str(select([1]).compile(dialect=e1.dialect))
+
+        with e1.connect() as conn:
+
+            result = conn.execute(stmt)
+
+        ctx = result.context
+        eq_(canary.bce.mock_calls,
+                [call(conn, ctx.cursor, stmt, ctx.parameters[0], ctx, False)])
+        eq_(canary.ace.mock_calls,
+                [call(conn, ctx.cursor, stmt, ctx.parameters[0], ctx, False)])
+
+
     def test_argument_format_execute(self):
         def before_execute(conn, clauseelement, multiparams, params):
             assert isinstance(multiparams, (list, tuple))