From: Mike Bayer Date: Fri, 11 Sep 2020 14:50:58 +0000 (-0400) Subject: Emit deprecation warning for **kw passed to session.execute() X-Git-Tag: rel_1_4_0b1~107^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fe6c3605df25d083c20f39fbd176a0c0a6736056;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Emit deprecation warning for **kw passed to session.execute() Passing keyword arguments to methods such as :meth:`_orm.Session.execute` to be passed into the :meth:`_orm.Session.get_bind` method is deprecated; the new :paramref:`_orm.Session.execute.bind_arguments` dictionary should be passed instead. Fixes: #5573 Change-Id: I555bda84384dbf6d12ba4483c486f9488be0fa25 --- diff --git a/doc/build/changelog/unreleased_14/5573.rst b/doc/build/changelog/unreleased_14/5573.rst new file mode 100644 index 0000000000..491dad80c8 --- /dev/null +++ b/doc/build/changelog/unreleased_14/5573.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: change, orm + :tickets: 5573 + + Passing keyword arguments to methods such as :meth:`_orm.Session.execute` + to be passed into the :meth:`_orm.Session.get_bind` method is deprecated; + the new :paramref:`_orm.Session.execute.bind_arguments` dictionary should + be passed instead. + diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 0c012d7f3f..535f030cf5 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -1561,10 +1561,18 @@ class Session(_SessionClassMethods): """ statement = coercions.expect(roles.CoerceTextStatementRole, statement) - if not bind_arguments: - bind_arguments = kw - elif kw: - bind_arguments.update(kw) + if kw: + util.warn_deprecated_20( + "Passing bind arguments to Session.execute() as keyword " + "arguments is deprecated and will be removed SQLAlchemy 2.0. " + "Please use the bind_arguments parameter." + ) + if not bind_arguments: + bind_arguments = kw + else: + bind_arguments.update(kw) + elif not bind_arguments: + bind_arguments = {} if future and ( statement._propagate_attrs.get("compile_state_plugin", None) @@ -1645,15 +1653,18 @@ class Session(_SessionClassMethods): self, statement, params=None, - execution_options=None, - mapper=None, - bind=None, + execution_options=util.EMPTY_DICT, + bind_arguments=None, **kw ): """Like :meth:`~.Session.execute` but return a scalar result.""" return self.execute( - statement, params=params, mapper=mapper, bind=bind, **kw + statement, + params=params, + execution_options=execution_options, + bind_arguments=bind_arguments, + **kw ).scalar() def close(self): diff --git a/test/orm/test_deprecations.py b/test/orm/test_deprecations.py index 43ab3d630a..0622d8916e 100644 --- a/test/orm/test_deprecations.py +++ b/test/orm/test_deprecations.py @@ -45,6 +45,7 @@ from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import is_true +from sqlalchemy.testing import mock from sqlalchemy.testing.mock import call from sqlalchemy.testing.mock import Mock from sqlalchemy.testing.schema import Column @@ -534,6 +535,40 @@ class SessionTest(fixtures.RemovesEvents, _LocalFixture): ): Session(autocommit=True) + @testing.combinations( + {"mapper": None}, + {"clause": None}, + {"bind_arguments": {"mapper": None}, "clause": None}, + {"bind_arguments": {}, "clause": None}, + ) + def test_bind_kwarg_deprecated(self, kw): + s1 = Session(testing.db) + + for meth in s1.execute, s1.scalar: + m1 = mock.Mock(side_effect=s1.get_bind) + with mock.patch.object(s1, "get_bind", m1): + expr = text("select 1") + + with testing.expect_deprecated_20( + r"Passing bind arguments to Session.execute\(\) as " + "keyword " + "arguments is deprecated and will be removed SQLAlchemy " + "2.0" + ): + meth(expr, **kw) + + bind_arguments = kw.pop("bind_arguments", None) + if bind_arguments: + bind_arguments.update(kw) + + if "clause" not in kw: + bind_arguments["clause"] = expr + eq_(m1.mock_calls, [call(**bind_arguments)]) + else: + if "clause" not in kw: + kw["clause"] = expr + eq_(m1.mock_calls, [call(**kw)]) + @testing.requires.independent_connections @testing.emits_warning(".*previous exception") def test_failed_rollback_deactivates_transaction_ctx_integration(self): diff --git a/test/orm/test_session.py b/test/orm/test_session.py index eec379f040..9bc6c6f7ce 100644 --- a/test/orm/test_session.py +++ b/test/orm/test_session.py @@ -562,7 +562,8 @@ class SessionStateTest(_fixtures.FixtureTest): assert u2 is u assert ( sess.execute( - "select count(1) from users", mapper=User + "select count(1) from users", + bind_arguments=dict(mapper=User), ).scalar() == 1 ) @@ -575,7 +576,8 @@ class SessionStateTest(_fixtures.FixtureTest): sess.commit() assert ( sess.execute( - "select count(1) from users", mapper=User + "select count(1) from users", + bind_arguments=dict(mapper=User), ).scalar() == 1 ) @@ -1928,13 +1930,13 @@ class SessionInterface(fixtures.TestBase): sa.exc.NoInspectionAvailable, callable_, *args, **kw ) - raises_("connection", mapper=user_arg) + raises_("connection", bind_arguments=dict(mapper=user_arg)) - raises_("execute", "SELECT 1", mapper=user_arg) + raises_("execute", "SELECT 1", bind_arguments=dict(mapper=user_arg)) raises_("get_bind", mapper=user_arg) - raises_("scalar", "SELECT 1", mapper=user_arg) + raises_("scalar", "SELECT 1", bind_arguments=dict(mapper=user_arg)) eq_( watchdog,