From: Mike Bayer Date: Wed, 19 Mar 2014 17:03:44 +0000 (-0400) Subject: - The :meth:`.ConnectionEvents.after_cursor_execute` event is now X-Git-Tag: rel_0_9_4~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a1a79b6ce53f2e1dc4cd48bbca5c5a148b8b285;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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. --- diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 87606c8d83..dcec53d1e0 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -14,6 +14,20 @@ .. 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 diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 888a15feea..d3024640bb 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 d3bd3c2cda..6efcdcb89c 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))