From: Daniel Lister Date: Thu, 24 Jan 2019 21:35:16 +0000 (-0500) Subject: Add getters for all execution_options X-Git-Tag: rel_1_3_0b2~7^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2bbd3ac1fb6049fc7195821798f02ce7fa56a7e9;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Add getters for all execution_options Added accessors for execution options to Core and ORM, via :meth:`.Query.get_execution_options`, :meth:`.Connection.get_execution_options`, :meth:`.Engine.get_execution_options`, and :meth:`.Executable.get_execution_options`. PR courtesy Daniel Lister. Fixes: #4406 Closes: #4465 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/4465 Pull-request-sha: 9674688bb5e80471a6a421bac06f995c2e64f8f7 Change-Id: I93ba51d7a2d687e255edd6938db15615e56dd237 --- diff --git a/doc/build/changelog/unreleased_13/4406.rst b/doc/build/changelog/unreleased_13/4406.rst new file mode 100644 index 0000000000..d97a0d830a --- /dev/null +++ b/doc/build/changelog/unreleased_13/4406.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, orm, engine + :tickets: 4406 + + Added accessors for execution options to Core and ORM, via + :meth:`.Query.get_execution_options`, + :meth:`.Connection.get_execution_options`, + :meth:`.Engine.get_execution_options`, and + :meth:`.Executable.get_execution_options`. PR courtesy Daniel Lister. diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 64303f2905..6467e91b9f 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -324,6 +324,15 @@ class Connection(Connectable): :ref:`schema_translating` + .. seealso:: + + :meth:`.Engine.execution_options` + + :meth:`.Executable.execution_options` + + :meth:`.Connection.get_execution_options` + + """ # noqa c = self._clone() c._execution_options = c._execution_options.union(opt) @@ -332,6 +341,17 @@ class Connection(Connectable): self.dialect.set_connection_execution_options(c, opt) return c + def get_execution_options(self): + """ Get the non-SQL options which will take effect during execution. + + .. versionadded:: 1.3 + + .. seealso:: + + :meth:`.Connection.execution_options` + """ + return self._execution_options + @property def closed(self): """Return True if this connection is closed.""" @@ -1932,9 +1952,23 @@ class Engine(Connectable, log.Identified): :meth:`.Engine.update_execution_options` - update the execution options for a given :class:`.Engine` in place. + :meth:`.Engine.get_execution_options` + + """ return OptionEngine(self, opt) + def get_execution_options(self): + """ Get the non-SQL options which will take effect during execution. + + .. versionadded: 1.3 + + .. seealso:: + + :meth:`.Engine.execution_options` + """ + return self._execution_options + @property def name(self): """String name of the :class:`~sqlalchemy.engine.interfaces.Dialect` diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 1503479951..2ba768241a 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1554,6 +1554,17 @@ class Query(object): """ return self.with_hint(None, text, dialect_name) + def get_execution_options(self): + """ Get the non-SQL options which will take effect during execution. + + .. versionadded:: 1.3 + + .. seealso:: + + :meth:`.Query.execution_options` + """ + return self._execution_options + @_generative() def execution_options(self, **kwargs): """ Set non-SQL options which take effect during execution. @@ -1565,6 +1576,10 @@ class Query(object): automatically if the :meth:`~sqlalchemy.orm.query.Query.yield_per()` method is used. + .. seealso:: + + :meth:`.Query.get_execution_options` + """ self._execution_options = self._execution_options.union(kwargs) diff --git a/lib/sqlalchemy/sql/base.py b/lib/sqlalchemy/sql/base.py index a5a0e4377b..c5e5fd8a1b 100644 --- a/lib/sqlalchemy/sql/base.py +++ b/lib/sqlalchemy/sql/base.py @@ -365,9 +365,11 @@ class Executable(Generative): .. seealso:: - :meth:`.Connection.execution_options()` + :meth:`.Connection.execution_options` - :meth:`.Query.execution_options()` + :meth:`.Query.execution_options` + + :meth:`.Executable.get_execution_options` """ if "isolation_level" in kw: @@ -384,6 +386,17 @@ class Executable(Generative): ) self._execution_options = self._execution_options.union(kw) + def get_execution_options(self): + """ Get the non-SQL options which will take effect during execution. + + .. versionadded:: 1.3 + + .. seealso:: + + :meth:`.Executable.execution_options` + """ + return self._execution_options + def execute(self, *multiparams, **params): """Compile and execute this :class:`.Executable`.""" e = self.bind diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py index 061dae0057..ad9144a382 100644 --- a/test/engine/test_execute.py +++ b/test/engine/test_execute.py @@ -1272,6 +1272,21 @@ class ExecutionOptionsTest(fixtures.TestBase): c2_branch = c2.connect() eq_(c2_branch._execution_options, {"foo": "bar"}) + def test_get_engine_execution_options(self): + engine = testing_engine("sqlite://") + engine.dialect = Mock() + e2 = engine.execution_options(foo="bar") + + eq_(e2.get_execution_options(), {"foo": "bar"}) + + def test_get_connection_execution_options(self): + engine = testing_engine("sqlite://", options=dict(_initialize=False)) + engine.dialect = Mock() + conn = engine.connect() + c = conn.execution_options(foo="bar") + + eq_(c.get_execution_options(), {"foo": "bar"}) + class EngineEventsTest(fixtures.TestBase): __requires__ = ("ad_hoc_engines",) diff --git a/test/orm/test_query.py b/test/orm/test_query.py index 0c8c27bb2c..4ec602e43c 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -5205,17 +5205,25 @@ class ExecutionOptionsTest(QueryTest): sess = create_session(bind=testing.db, autocommit=False) q1 = sess.query(User) - assert q1._execution_options == dict() + eq_(q1._execution_options, dict()) q2 = q1.execution_options(foo="bar", stream_results=True) # q1's options should be unchanged. - assert q1._execution_options == dict() + eq_(q1._execution_options, dict()) # q2 should have them set. - assert q2._execution_options == dict(foo="bar", stream_results=True) + eq_(q2._execution_options, dict(foo="bar", stream_results=True)) q3 = q2.execution_options(foo="not bar", answer=42) - assert q2._execution_options == dict(foo="bar", stream_results=True) + eq_(q2._execution_options, dict(foo="bar", stream_results=True)) q3_options = dict(foo="not bar", stream_results=True, answer=42) - assert q3._execution_options == q3_options + eq_(q3._execution_options, q3_options) + + def test_get_options(self): + User = self.classes.User + + sess = create_session(bind=testing.db, autocommit=False) + + q = sess.query(User).execution_options(foo="bar", stream_results=True) + eq_(q.get_execution_options(), dict(foo="bar", stream_results=True)) def test_options_in_connection(self): User = self.classes.User diff --git a/test/sql/test_generative.py b/test/sql/test_generative.py index f030f1d9ca..ccb5b15ead 100644 --- a/test/sql/test_generative.py +++ b/test/sql/test_generative.py @@ -1769,10 +1769,10 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL): s2 = s.execution_options(bar="baz") s3 = s.execution_options(foo="not bar") # The original select should not be modified. - assert s._execution_options == dict(foo="bar") + eq_(s.get_execution_options(), dict(foo="bar")) # s2 should have its execution_options based on s, though. - assert s2._execution_options == dict(foo="bar", bar="baz") - assert s3._execution_options == dict(foo="not bar") + eq_(s2.get_execution_options(), dict(foo="bar", bar="baz")) + eq_(s3.get_execution_options(), dict(foo="not bar")) def test_invalid_options(self): assert_raises(