Add deprecation for base Executable.bind

These attributes will be removed in SQLAlchemy 2.0.

Also alters the deprecation message to qualify the
type of object correctly.  this in turn requires changes
in the warnings filter and deprecation tests.

Change-Id: I5779d9813e88f42e5db0c7b5e3ffff1d1535c203
This commit is contained in:
Mike Bayer
2020-10-16 12:03:11 -04:00
parent 41d3e16773
commit 5162f2bc5f
13 changed files with 73 additions and 59 deletions
+4
View File
@@ -904,6 +904,10 @@ class Executable(Generative):
return self.execute(*multiparams, **params).scalar()
@property
@util.deprecated_20(
":attr:`.Executable.bind`",
alternative="Bound metadata is being removed as of SQLAlchemy 2.0.",
)
def bind(self):
"""Returns the :class:`_engine.Engine` or :class:`_engine.Connection`
to
+23
View File
@@ -1221,7 +1221,14 @@ class Join(roles.DMLTableRole, FromClause):
).select_from(self)
@property
@util.deprecated_20(
":attr:`.Executable.bind`",
alternative="Bound metadata is being removed as of SQLAlchemy 2.0.",
)
def bind(self):
"""Return the bound engine associated with either the left or right
side of this :class:`_sql.Join`."""
return self.left.bind or self.right.bind
@util.preload_module("sqlalchemy.sql.util")
@@ -3487,7 +3494,15 @@ class CompoundSelect(HasCompileState, GenerativeSelect):
return self.selects[0].selected_columns
@property
@util.deprecated_20(
":attr:`.Executable.bind`",
alternative="Bound metadata is being removed as of SQLAlchemy 2.0.",
)
def bind(self):
"""Returns the :class:`_engine.Engine` or :class:`_engine.Connection`
to which this :class:`.Executable` is bound, or None if none found.
"""
if self._bind:
return self._bind
for s in self.selects:
@@ -5348,7 +5363,15 @@ class Select(
return CompoundSelect._create_intersect_all(self, other, **kwargs)
@property
@util.deprecated_20(
":attr:`.Executable.bind`",
alternative="Bound metadata is being removed as of SQLAlchemy 2.0.",
)
def bind(self):
"""Returns the :class:`_engine.Engine` or :class:`_engine.Connection`
to which this :class:`.Executable` is bound, or None if none found.
"""
if self._bind:
return self._bind
+11 -10
View File
@@ -50,13 +50,13 @@ def setup_filters():
#
# Core execution
#
r"The (?:Executable|Engine)\.(?:execute|scalar)\(\) function",
r"The (?:Executable|Engine)\.(?:execute|scalar)\(\) method",
r"The current statement is being autocommitted using implicit "
"autocommit,",
r"The connection.execute\(\) method in SQLAlchemy 2.0 will accept "
"parameters as a single dictionary or a single sequence of "
"dictionaries only.",
r"The Connection.connect\(\) function/method is considered legacy",
r"The Connection.connect\(\) method is considered legacy",
r".*DefaultGenerator.execute\(\)",
r"The autoload parameter is deprecated and will be removed ",
#
@@ -65,10 +65,11 @@ def setup_filters():
#
r"The MetaData.bind argument is deprecated",
r"The ``bind`` argument for schema methods that invoke SQL ",
r"The Executable.bind attribute is considered legacy ",
#
# result sets
#
r"The Row.keys\(\) function/method",
r"The Row.keys\(\) method",
r"Using non-integer/slice indices on Row ",
#
# Core SQL constructs
@@ -106,18 +107,18 @@ def setup_filters():
#
# ORM Query
#
r"The Query\.get\(\) function",
r"The Query\.from_self\(\) function",
r"The Query\.with_parent\(\) function",
r"The Query\.with_parent\(\) function",
r"The Query\.select_entity_from\(\) function",
r"The Query\.get\(\) method",
r"The Query\.from_self\(\) method",
r"The Query\.with_parent\(\) method",
r"The Query\.with_parent\(\) method",
r"The Query\.select_entity_from\(\) method",
r"The ``aliased`` and ``from_joinpoint`` keyword arguments",
r"Using strings to indicate relationship names in Query.join",
r"Using strings to indicate column or relationship paths in "
"loader options",
r"Using strings to indicate relationship names in the ORM "
r"with_parent\(\)",
r"The Query.with_polymorphic\(\) function/method is considered "
r"The Query.with_polymorphic\(\) method is considered "
"legacy as of the 1.x series",
r"Passing a chain of multiple join conditions to Query.join\(\) "
r"is deprecated and will be removed in SQLAlchemy 2.0.",
@@ -130,7 +131,7 @@ def setup_filters():
r".*object is being merged into a Session along the backref "
"cascade path",
r"Passing bind arguments to Session.execute\(\) as keyword arguments",
r"The Session.transaction function/method",
r"The Session.transaction attribute",
r"The merge_result\(\) method is superseded by the "
r"merge_frozen_result\(\)",
r"The Session.begin.subtransactions flag is deprecated",
+10 -2
View File
@@ -162,9 +162,17 @@ def moved_20(message, **kw):
def deprecated_20(api_name, alternative=None, **kw):
type_reg = re.match("^:(attr|func|meth):", api_name)
if type_reg:
type_ = {"attr": "attribute", "func": "function", "meth": "method"}[
type_reg.group(1)
]
else:
type_ = "construct"
message = (
"The %s function/method is considered legacy as of the "
"1.x series of SQLAlchemy and will be removed in 2.0." % api_name
"The %s %s is considered legacy as of the "
"1.x series of SQLAlchemy and will be removed in 2.0."
% (api_name, type_)
)
if alternative:
+7 -7
View File
@@ -91,7 +91,7 @@ class ConnectionlessDeprecationTest(fixtures.TestBase):
conn = e.connect()
with testing.expect_deprecated_20(
r"The Connection.connect\(\) function/method is considered",
r"The Connection.connect\(\) method is considered",
r"The .close\(\) method on a so-called 'branched' connection is "
r"deprecated as of 1.4, as are 'branched' connections overall, "
r"and will be removed in a future release.",
@@ -108,13 +108,13 @@ class ConnectionlessDeprecationTest(fixtures.TestBase):
stmt = table.insert().values(a=1)
with testing.expect_deprecated_20(
r"The Engine.execute\(\) function/method is considered legacy",
r"The Engine.execute\(\) method is considered legacy",
):
testing.db.execute(stmt)
stmt = select(table)
with testing.expect_deprecated_20(
r"The Engine.execute\(\) function/method is considered legacy",
r"The Engine.execute\(\) method is considered legacy",
):
eq_(testing.db.execute(stmt).fetchall(), [(1,)])
@@ -125,13 +125,13 @@ class ConnectionlessDeprecationTest(fixtures.TestBase):
stmt = table.insert().values(a=1)
with testing.expect_deprecated_20(
r"The Executable.execute\(\) function/method is considered legacy",
r"The Executable.execute\(\) method is considered legacy",
):
stmt.execute()
stmt = select(table)
with testing.expect_deprecated_20(
r"The Executable.execute\(\) function/method is considered legacy",
r"The Executable.execute\(\) method is considered legacy",
):
eq_(stmt.execute().fetchall(), [(1,)])
@@ -581,7 +581,7 @@ class DeprecatedReflectionTest(fixtures.TablesTest):
metadata = self.metadata
table = Table("user", metadata)
with testing.expect_deprecated_20(
r"The Inspector.reflecttable\(\) function/method is considered "
r"The Inspector.reflecttable\(\) method is considered "
):
res = inspector.reflecttable(table, None)
exp = inspector.reflect_table(table, None)
@@ -597,7 +597,7 @@ class ExecutionOptionsTest(fixtures.TestBase):
c2 = conn.execution_options(foo="bar")
with testing.expect_deprecated_20(
r"The Connection.connect\(\) function/method is considered "
r"The Connection.connect\(\) method is considered "
):
c2_branch = c2.connect()
eq_(c2_branch._execution_options, {"foo": "bar"})
+1 -1
View File
@@ -3292,7 +3292,7 @@ class FutureExecuteTest(fixtures.FutureEngineMixin, fixtures.TablesTest):
def test_no_branching(self, connection):
with testing.expect_deprecated(
r"The Connection.connect\(\) function/method is considered legacy"
r"The Connection.connect\(\) method is considered legacy"
):
assert_raises_message(
NotImplementedError,
+2 -6
View File
@@ -577,9 +577,7 @@ class ConcreteTest(fixtures.MappedTest):
# test adaption of the column by wrapping the query in a
# subquery
with testing.expect_deprecated(
r"The Query.from_self\(\) function/method"
):
with testing.expect_deprecated(r"The Query.from_self\(\) method"):
eq_(
len(
session.connection()
@@ -593,9 +591,7 @@ class ConcreteTest(fixtures.MappedTest):
),
2,
)
with testing.expect_deprecated(
r"The Query.from_self\(\) function/method"
):
with testing.expect_deprecated(r"The Query.from_self\(\) method"):
eq_(
set(
[
@@ -62,7 +62,7 @@ class PolymorphicCircularTest(fixtures.MappedTest):
# }, None, 'pjoin')
with testing.expect_deprecated_20(
r"The Join.alias\(\) function/method is considered legacy"
r"The Join.alias\(\) method is considered legacy"
):
join = table1.outerjoin(table2).outerjoin(table3).alias("pjoin")
# join = None
+2 -6
View File
@@ -1553,9 +1553,7 @@ class _PolymorphicTestBase(object):
palias = aliased(Person)
expected = [(m1, e1), (m1, e2), (m1, b1)]
with testing.expect_deprecated(
r"The Query.from_self\(\) function/method"
):
with testing.expect_deprecated(r"The Query.from_self\(\) method"):
eq_(
sess.query(Person, palias)
.filter(Person.company_id == palias.company_id)
@@ -1575,9 +1573,7 @@ class _PolymorphicTestBase(object):
expected = [(m1, e1), (m1, e2), (m1, b1)]
with testing.expect_deprecated(
r"The Query.from_self\(\) function/method"
):
with testing.expect_deprecated(r"The Query.from_self\(\) method"):
eq_(
sess.query(palias, palias2)
.filter(palias.company_id == palias2.company_id)
+2 -6
View File
@@ -1736,9 +1736,7 @@ class SubClassToSubClassMultiTest(AssertsCompiledSQL, fixtures.MappedTest):
# this query is coming out instead which is equivalent, but not
# totally sure where this happens
with testing.expect_deprecated(
r"The Query.from_self\(\) function/method"
):
with testing.expect_deprecated(r"The Query.from_self\(\) method"):
self.assert_compile(
s.query(Sub2).from_self().join(Sub2.ep1).join(Sub2.ep2),
"SELECT anon_1.sub2_id AS anon_1_sub2_id, "
@@ -1789,9 +1787,7 @@ class SubClassToSubClassMultiTest(AssertsCompiledSQL, fixtures.MappedTest):
# I3abfb45dd6e50f84f29d39434caa0b550ce27864,
# this query is coming out instead which is equivalent, but not
# totally sure where this happens
with testing.expect_deprecated(
r"The Query.from_self\(\) function/method"
):
with testing.expect_deprecated(r"The Query.from_self\(\) method"):
self.assert_compile(
# adding Sub2 to the entities list helps it,
+2 -6
View File
@@ -284,9 +284,7 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
Engineer = self.classes.Engineer
sess = create_session()
with testing.expect_deprecated(
r"The Query.from_self\(\) function/method"
):
with testing.expect_deprecated(r"The Query.from_self\(\) method"):
self.assert_compile(
sess.query(Engineer).from_self(),
"SELECT anon_1.employees_employee_id AS "
@@ -423,9 +421,7 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
sess = create_session()
col = func.count(literal_column("*"))
with testing.expect_deprecated(
r"The Query.from_self\(\) function/method"
):
with testing.expect_deprecated(r"The Query.from_self\(\) method"):
self.assert_compile(
sess.query(Engineer.employee_id).from_self(col),
"SELECT count(*) AS count_1 "
+4 -10
View File
@@ -76,7 +76,7 @@ join_aliased_dep = (
)
w_polymorphic_dep = (
r"The Query.with_polymorphic\(\) function/method is "
r"The Query.with_polymorphic\(\) method is "
"considered legacy as of the 1.x series"
)
@@ -946,9 +946,7 @@ class SelfRefFromSelfTest(fixtures.MappedTest, AssertsCompiledSQL):
)
def _from_self_deprecated(self):
return testing.expect_deprecated_20(
r"The Query.from_self\(\) function/method"
)
return testing.expect_deprecated_20(r"The Query.from_self\(\) method")
class DynamicTest(_DynamicFixture, _fixtures.FixtureTest):
@@ -982,9 +980,7 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
__dialect__ = "default"
def _from_self_deprecated(self):
return testing.expect_deprecated_20(
r"The Query.from_self\(\) function/method"
)
return testing.expect_deprecated_20(r"The Query.from_self\(\) method")
def test_illegal_operations(self):
@@ -1826,9 +1822,7 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
class SubqRelationsFromSelfTest(fixtures.DeclarativeMappedTest):
def _from_self_deprecated(self):
return testing.expect_deprecated_20(
r"The Query.from_self\(\) function/method"
)
return testing.expect_deprecated_20(r"The Query.from_self\(\) method")
@classmethod
def setup_classes(cls):
+4 -4
View File
@@ -724,7 +724,7 @@ class SelectableTest(fixtures.TestBase, AssertsCompiledSQL):
j1 = self.table1.join(self.table2)
with testing.expect_deprecated_20(
r"The Join.alias\(\) function/method is considered legacy"
r"The Join.alias\(\) method is considered legacy"
):
self.assert_compile(
j1.alias(),
@@ -737,7 +737,7 @@ class SelectableTest(fixtures.TestBase, AssertsCompiledSQL):
)
with testing.expect_deprecated_20(
r"The Join.alias\(\) function/method is considered legacy"
r"The Join.alias\(\) method is considered legacy"
):
self.assert_compile(
j1.alias(flat=True),
@@ -769,7 +769,7 @@ class SelectableTest(fixtures.TestBase, AssertsCompiledSQL):
# test alias of the join
with testing.expect_deprecated(
r"The Join.alias\(\) function/method is considered legacy"
r"The Join.alias\(\) method is considered legacy"
):
j2 = jjj.alias("foo")
assert (
@@ -1589,7 +1589,7 @@ class CursorResultTest(fixtures.TablesTest):
).first()
with testing.expect_deprecated_20(
r"The Row.keys\(\) function/method is considered legacy "
r"The Row.keys\(\) method is considered legacy "
):
eq_(r.keys(), ["user_id", "user_name"])