From 8bf920d52ddd4ec5f62a00fb9db370a076aa375d Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 23 Mar 2021 10:23:23 -0400 Subject: [PATCH] warn / document for Query.with_polymorphic() with with_loader_criteria() These are illustrated as not working in #6111. As this is a highly complex and legacy method, encourage users to migrate off of it before using with_loader_criteria(). Fixes: #6111 Change-Id: I63c8187020c631d83259ea2200b66eabf74a0d0d --- lib/sqlalchemy/orm/query.py | 13 +++++++++++-- lib/sqlalchemy/orm/util.py | 7 +++++++ test/orm/test_deprecations.py | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 96b4c56244..7e2fde7497 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -786,6 +786,14 @@ class Query( ): """Load columns for inheriting classes. + This is a legacy method which is replaced by the + :func:`_orm.with_polymorphic` function. + + .. warning:: The :meth:`_orm.Query.with_polymorphic` method does + **not** support 1.4/2.0 style features including + :func:`_orm.with_loader_criteria`. Please migrate code + to use :func:`_orm.with_polymorphic`. + :meth:`_query.Query.with_polymorphic` applies transformations to the "main" mapped class represented by this :class:`_query.Query`. The "main" mapped class here means the :class:`_query.Query` @@ -796,8 +804,9 @@ class Query( purposes of load-time efficiency as well as the ability to use these columns at query time. - See the documentation section :ref:`with_polymorphic` for - details on how this method is used. + .. seealso:: + + :ref:`with_polymorphic` - illustrates current patterns """ diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 37be077be7..941c5eb085 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -1070,6 +1070,13 @@ class LoaderCriteriaOption(CriteriaOption): # if options to limit the criteria to immediate query only, # use compile_state.attributes instead + if compile_state.compile_options._with_polymorphic_adapt_map: + util.warn( + "The with_loader_criteria() function may not work " + "correctly with the legacy Query.with_polymorphic() feature. " + "Please migrate code to use the with_polymorphic() standalone " + "function before using with_loader_criteria()." + ) if not compile_state.compile_options._for_refresh_state: self.get_global_criteria(compile_state.global_attributes) diff --git a/test/orm/test_deprecations.py b/test/orm/test_deprecations.py index 34e3a48312..dd7e79ffd1 100644 --- a/test/orm/test_deprecations.py +++ b/test/orm/test_deprecations.py @@ -42,6 +42,7 @@ from sqlalchemy.orm import Session from sqlalchemy.orm import subqueryload from sqlalchemy.orm import synonym from sqlalchemy.orm import undefer +from sqlalchemy.orm import with_loader_criteria from sqlalchemy.orm import with_parent from sqlalchemy.orm import with_polymorphic from sqlalchemy.orm.collections import collection @@ -5056,6 +5057,27 @@ class InheritedJoinTest(_poly_fixtures._Polymorphic, AssertsCompiledSQL): use_default_dialect=True, ) + def test_with_poly_loader_criteria_warning(self): + Person, Manager = ( + self.classes.Person, + self.classes.Manager, + ) + + sess = fixture_session() + + with testing.expect_deprecated_20(w_polymorphic_dep): + q = ( + sess.query(Person) + .with_polymorphic(Manager) + .options(with_loader_criteria(Person, Person.person_id == 1)) + ) + + with testing.expect_warnings( + r"The with_loader_criteria\(\) function may not work " + r"correctly with the legacy Query.with_polymorphic\(\)" + ): + str(q) + class JoinFromSelectableTest(fixtures.MappedTest, AssertsCompiledSQL): __dialect__ = "default" -- 2.47.2