summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-03-19 13:03:44 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2014-03-19 13:03:44 -0400
commit2a1a79b6ce53f2e1dc4cd48bbca5c5a148b8b285 (patch)
tree40acfcb869ba3747e531c172627d2bccd13d18f4
parent89a8e0d187b8967c9b8291bcdc3078335704dbfa (diff)
downloadsqlalchemy-2a1a79b6ce53f2e1dc4cd48bbca5c5a148b8b285.tar.gz
- 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.
-rw-r--r--doc/build/changelog/changelog_09.rst14
-rw-r--r--lib/sqlalchemy/engine/base.py15
-rw-r--r--test/engine/test_execute.py42
3 files changed, 67 insertions, 4 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst
index 87606c8d8..dcec53d1e 100644
--- a/doc/build/changelog/changelog_09.rst
+++ b/doc/build/changelog/changelog_09.rst
@@ -15,6 +15,20 @@
: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
Added support for the not-quite-yet-documented ``insert=True``
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index 888a15fee..d3024640b 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -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
diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py
index d3bd3c2cd..6efcdcb89 100644
--- a/test/engine/test_execute.py
+++ b/test/engine/test_execute.py
@@ -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))