summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2021-10-20 12:50:53 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2021-10-25 12:09:41 -0400
commit92aa35e7fc737de58c25d6c22bf1c48f6c4c714b (patch)
treef3c46d6d198441bb7f8ca7e8a7b2322b26491782
parent605d0d905855684bfe4409532af98f336ae38f82 (diff)
downloadsqlalchemy-92aa35e7fc737de58c25d6c22bf1c48f6c4c714b.tar.gz
deprecation warnings: strings in loader options, join, with_parent
Repairs one in-library deprecation warning regarding mapper propagation of options raises maxfail to 250, as 25 is too low when we are trying to address many errors at once. the 25 was originally due to the fact that our fixtures would be broken after that many failures in most cases, which today should not be the case nearly as often. Change-Id: I26affddf42e2cae2aaf9561633e9b8cd431eb189
-rw-r--r--lib/sqlalchemy/ext/associationproxy.py19
-rw-r--r--lib/sqlalchemy/orm/mapper.py10
-rw-r--r--lib/sqlalchemy/orm/strategy_options.py3
-rw-r--r--lib/sqlalchemy/testing/warnings.py8
-rw-r--r--setup.cfg2
-rw-r--r--test/ext/test_associationproxy.py10
-rw-r--r--test/ext/test_horizontal_shard.py2
-rw-r--r--test/orm/inheritance/test_assorted_poly.py12
-rw-r--r--test/orm/inheritance/test_basic.py2
-rw-r--r--test/orm/inheritance/test_polymorphic_rel.py64
-rw-r--r--test/orm/inheritance/test_relationship.py23
-rw-r--r--test/orm/inheritance/test_single.py6
-rw-r--r--test/orm/test_ac_relationships.py8
-rw-r--r--test/orm/test_assorted_eager.py26
-rw-r--r--test/orm/test_cache_key.py44
-rw-r--r--test/orm/test_composites.py4
-rw-r--r--test/orm/test_default_strategies.py96
-rw-r--r--test/orm/test_deferred.py135
-rw-r--r--test/orm/test_deprecations.py1343
-rw-r--r--test/orm/test_eager_relations.py20
-rw-r--r--test/orm/test_expire.py10
-rw-r--r--test/orm/test_froms.py180
-rw-r--r--test/orm/test_generative.py10
-rw-r--r--test/orm/test_joins.py11
-rw-r--r--test/orm/test_lazy_relations.py6
-rw-r--r--test/orm/test_mapper.py16
-rw-r--r--test/orm/test_merge.py4
-rw-r--r--test/orm/test_of_type.py3
-rw-r--r--test/orm/test_options.py306
-rw-r--r--test/orm/test_pickled.py26
-rw-r--r--test/orm/test_query.py146
-rw-r--r--test/orm/test_relationships.py16
-rw-r--r--test/orm/test_selectin_relations.py27
-rw-r--r--test/orm/test_subquery_relations.py32
-rw-r--r--test/orm/test_unitofwork.py2
35 files changed, 1792 insertions, 840 deletions
diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py
index 411033a6b..dd5c10ac9 100644
--- a/lib/sqlalchemy/ext/associationproxy.py
+++ b/lib/sqlalchemy/ext/associationproxy.py
@@ -472,10 +472,23 @@ class AssociationProxyInstance(object):
def attr(self):
"""Return a tuple of ``(local_attr, remote_attr)``.
- This attribute is convenient when specifying a join
- using :meth:`_query.Query.join` across two relationships::
+ This attribute was originally intended to facilitate using the
+ :meth:`_query.Query.join` method to join across the two relationships
+ at once, however this makes use of a deprecated calling style.
+
+ To use :meth:`_sql.select.join` or :meth:`_orm.Query.join` with
+ an association proxy, the current method is to make use of the
+ :attr:`.AssociationProxyInstance.local_attr` and
+ :attr:`.AssociationProxyInstance.remote_attr` attributes separately::
+
+ stmt = (
+ select(Parent).
+ join(Parent.proxied.local_attr).
+ join(Parent.proxied.remote_attr)
+ )
- sess.query(Parent).join(*Parent.proxied.attr)
+ A future release may seek to provide a more succinct join pattern
+ for association proxy attributes.
.. seealso::
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 1aa6666a5..4de12b88c 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -3111,14 +3111,20 @@ class Mapper(
# "enable" options, to turn on the properties that we want to
# load by default (subject to options from the query)
enable_opt.set_generic_strategy(
- (prop.key,), dict(prop.strategy_key)
+ # convert string name to an attribute before passing
+ # to loader strategy
+ (getattr(entity.entity_namespace, prop.key),),
+ dict(prop.strategy_key),
)
else:
# "disable" options, to turn off the properties from the
# superclass that we *don't* want to load, applied after
# the options from the query to override them
disable_opt.set_generic_strategy(
- (prop.key,), {"do_nothing": True}
+ # convert string name to an attribute before passing
+ # to loader strategy
+ (getattr(entity.entity_namespace, prop.key),),
+ {"do_nothing": True},
)
primary_key = [
diff --git a/lib/sqlalchemy/orm/strategy_options.py b/lib/sqlalchemy/orm/strategy_options.py
index b7ed4e89b..675c7218b 100644
--- a/lib/sqlalchemy/orm/strategy_options.py
+++ b/lib/sqlalchemy/orm/strategy_options.py
@@ -301,6 +301,7 @@ class Load(Generative, LoaderOption):
)
if isinstance(attr, util.string_types):
+
default_token = attr.endswith(_DEFAULT_TOKEN)
attr_str_name = attr
if attr.endswith(_WILDCARD_TOKEN) or default_token:
@@ -328,7 +329,7 @@ class Load(Generative, LoaderOption):
"Using strings to indicate column or "
"relationship paths in loader options is deprecated "
"and will be removed in SQLAlchemy 2.0. Please use "
- "the class-bound attribute directly."
+ "the class-bound attribute directly.",
)
try:
# use getattr on the class to work around
diff --git a/lib/sqlalchemy/testing/warnings.py b/lib/sqlalchemy/testing/warnings.py
index 9e02a0c03..9886b122d 100644
--- a/lib/sqlalchemy/testing/warnings.py
+++ b/lib/sqlalchemy/testing/warnings.py
@@ -73,16 +73,8 @@ def setup_filters():
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\(\) 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.",
- r"Query.join\(\) will no longer accept tuples as arguments",
#
# ORM Session
#
diff --git a/setup.cfg b/setup.cfg
index 7df0ad5c8..f432561b1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -92,7 +92,7 @@ tag_build = dev
where = lib
[tool:pytest]
-addopts = --tb native -v -r sfxX --maxfail=25 -p no:warnings -p no:logging
+addopts = --tb native -v -r sfxX --maxfail=250 -p no:warnings -p no:logging
python_files = test/*test_*.py
[upload]
diff --git a/test/ext/test_associationproxy.py b/test/ext/test_associationproxy.py
index bbb430a6f..258ecb90c 100644
--- a/test/ext/test_associationproxy.py
+++ b/test/ext/test_associationproxy.py
@@ -2277,9 +2277,9 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
def test_join_separate_attr(self):
User = self.classes.User
self.assert_compile(
- self.session.query(User).join(
- User.keywords.local_attr, User.keywords.remote_attr
- ),
+ self.session.query(User)
+ .join(User.keywords.local_attr)
+ .join(User.keywords.remote_attr),
"SELECT users.id AS users_id, users.name AS users_name, "
"users.singular_id AS users_singular_id "
"FROM users JOIN userkeywords ON users.id = "
@@ -2290,7 +2290,9 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
def test_join_single_attr(self):
User = self.classes.User
self.assert_compile(
- self.session.query(User).join(*User.keywords.attr),
+ self.session.query(User)
+ .join(User.keywords.attr[0])
+ .join(User.keywords.attr[1]),
"SELECT users.id AS users_id, users.name AS users_name, "
"users.singular_id AS users_singular_id "
"FROM users JOIN userkeywords ON users.id = "
diff --git a/test/ext/test_horizontal_shard.py b/test/ext/test_horizontal_shard.py
index a0bc8bbe5..192617901 100644
--- a/test/ext/test_horizontal_shard.py
+++ b/test/ext/test_horizontal_shard.py
@@ -863,7 +863,7 @@ class SelectinloadRegressionTest(fixtures.DeclarativeMappedTest):
session.add(book)
session.commit()
- result = session.query(Book).options(selectinload("pages")).all()
+ result = session.query(Book).options(selectinload(Book.pages)).all()
eq_(result, [book])
diff --git a/test/orm/inheritance/test_assorted_poly.py b/test/orm/inheritance/test_assorted_poly.py
index 2db4641dd..729e1ee04 100644
--- a/test/orm/inheritance/test_assorted_poly.py
+++ b/test/orm/inheritance/test_assorted_poly.py
@@ -641,7 +641,7 @@ class RelationshipTest4(fixtures.MappedTest):
def go():
testcar = session.get(
- Car, car1.car_id, options=[joinedload("employee")]
+ Car, car1.car_id, options=[joinedload(Car.employee)]
)
assert str(testcar.employee) == "Engineer E4, status X"
@@ -662,7 +662,7 @@ class RelationshipTest4(fixtures.MappedTest):
testcar = session.get(
Car,
car1.car_id,
- options=[joinedload("employee")],
+ options=[joinedload(Car.employee)],
)
assert str(testcar.employee) == "Engineer E4, status X"
@@ -670,7 +670,7 @@ class RelationshipTest4(fixtures.MappedTest):
session.expunge_all()
s = session.query(Car)
- c = s.join("employee").filter(Person.name == "E4")[0]
+ c = s.join(Car.employee).filter(Person.name == "E4")[0]
assert c.car_id == car1.car_id
@@ -1449,7 +1449,7 @@ class GenerativeTest(fixtures.MappedTest, AssertsExecutionResults):
r = (
session.query(Person)
.filter(Person.name.like("%2"))
- .join("status")
+ .join(Person.status)
.filter_by(name="active")
.order_by(Person.person_id)
)
@@ -1472,7 +1472,7 @@ class GenerativeTest(fixtures.MappedTest, AssertsExecutionResults):
session = fixture_session()
r = (
session.query(Engineer)
- .join("status")
+ .join(Engineer.status)
.filter(
Person.name.in_(["E2", "E3", "E4", "M4", "M2", "M1"])
& (Status.name == "active")
@@ -2226,7 +2226,7 @@ class Ticket2419Test(fixtures.DeclarativeMappedTest):
s.commit()
- q = s.query(B, B.ds.any(D.id == 1)).options(joinedload("es"))
+ q = s.query(B, B.ds.any(D.id == 1)).options(joinedload(B.es))
q = q.join(C, C.b_id == B.id)
q = q.limit(5)
eq_(q.all(), [(b, True)])
diff --git a/test/orm/inheritance/test_basic.py b/test/orm/inheritance/test_basic.py
index 52b362b9e..e870a80f0 100644
--- a/test/orm/inheritance/test_basic.py
+++ b/test/orm/inheritance/test_basic.py
@@ -224,7 +224,7 @@ class PolyExpressionEagerLoad(fixtures.DeclarativeMappedTest):
result = (
session.query(A)
.filter_by(child_id=None)
- .options(joinedload("child"))
+ .options(joinedload(A.child))
.one()
)
diff --git a/test/orm/inheritance/test_polymorphic_rel.py b/test/orm/inheritance/test_polymorphic_rel.py
index 1a96ee011..b9d9ad932 100644
--- a/test/orm/inheritance/test_polymorphic_rel.py
+++ b/test/orm/inheritance/test_polymorphic_rel.py
@@ -332,7 +332,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess = fixture_session()
eq_(
sess.query(Person)
- .join("paperwork")
+ .join(Person.paperwork)
.filter(Paperwork.description.like("%review%"))
.all(),
[b1, m1],
@@ -357,7 +357,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.order_by(Person.person_id)
- .join("paperwork")
+ .join(Person.paperwork)
.filter(Paperwork.description.like("%#2%"))
.all(),
[e1, m1],
@@ -368,7 +368,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Engineer)
.order_by(Person.person_id)
- .join("paperwork")
+ .join(Person.paperwork)
.filter(Paperwork.description.like("%#2%"))
.all(),
[e1],
@@ -379,7 +379,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.order_by(Person.person_id)
- .join("paperwork")
+ .join(Person.paperwork)
.filter(Person.name.like("%dog%"))
.filter(Paperwork.description.like("%#2%"))
.all(),
@@ -391,7 +391,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.order_by(Person.person_id)
- .join("paperwork", aliased=True)
+ .join(Person.paperwork, aliased=True)
.filter(Paperwork.description.like("%review%"))
.all(),
[b1, m1],
@@ -420,7 +420,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.order_by(Person.person_id)
- .join(pa, "paperwork")
+ .join(pa, Person.paperwork)
.filter(pa.description.like("%review%"))
.all(),
[b1, m1],
@@ -431,7 +431,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.order_by(Person.person_id)
- .join("paperwork", aliased=True)
+ .join(Person.paperwork, aliased=True)
.filter(Paperwork.description.like("%#2%"))
.all(),
[e1, m1],
@@ -443,7 +443,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.order_by(Person.person_id)
- .join(pa, "paperwork")
+ .join(pa, Person.paperwork)
.filter(pa.description.like("%#2%"))
.all(),
[e1, m1],
@@ -454,7 +454,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Engineer)
.order_by(Person.person_id)
- .join("paperwork", aliased=True)
+ .join(Person.paperwork, aliased=True)
.filter(Paperwork.description.like("%#2%"))
.all(),
[e1],
@@ -466,7 +466,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Engineer)
.order_by(Person.person_id)
- .join(pa, "paperwork")
+ .join(pa, Person.paperwork)
.filter(pa.description.like("%#2%"))
.all(),
[e1],
@@ -478,7 +478,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.order_by(Person.person_id)
- .join(pa, "paperwork")
+ .join(pa, Person.paperwork)
.filter(Person.name.like("%dog%"))
.filter(pa.description.like("%#2%"))
.all(),
@@ -491,7 +491,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess.query(Person)
.with_polymorphic(Manager)
.order_by(Person.person_id)
- .join("paperwork")
+ .join(Person.paperwork)
.filter(Paperwork.description.like("%review%"))
.all(),
[b1, m1],
@@ -520,7 +520,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess.query(Person)
.with_polymorphic([Manager, Engineer])
.order_by(Person.person_id)
- .join("paperwork")
+ .join(Person.paperwork)
.filter(Paperwork.description.like("%#2%"))
.all(),
[e1, m1],
@@ -532,7 +532,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess.query(Person)
.with_polymorphic([Manager, Engineer])
.order_by(Person.person_id)
- .join("paperwork")
+ .join(Person.paperwork)
.filter(Person.name.like("%dog%"))
.filter(Paperwork.description.like("%#2%"))
.all(),
@@ -544,7 +544,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.with_polymorphic(Manager)
- .join("paperwork", aliased=True)
+ .join(Person.paperwork, aliased=True)
.filter(Paperwork.description.like("%review%"))
.all(),
[b1, m1],
@@ -556,7 +556,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
eq_(
sess.query(Person)
.with_polymorphic(Manager)
- .join(pa, "paperwork")
+ .join(pa, Person.paperwork)
.filter(pa.description.like("%review%"))
.all(),
[b1, m1],
@@ -568,7 +568,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess.query(Person)
.with_polymorphic([Manager, Engineer])
.order_by(Person.person_id)
- .join("paperwork", aliased=True)
+ .join(Person.paperwork, aliased=True)
.filter(Paperwork.description.like("%#2%"))
.all(),
[e1, m1],
@@ -581,7 +581,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess.query(Person)
.with_polymorphic([Manager, Engineer])
.order_by(Person.person_id)
- .join(pa, "paperwork")
+ .join(pa, Person.paperwork)
.filter(pa.description.like("%#2%"))
.all(),
[e1, m1],
@@ -595,7 +595,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess.query(Person)
.with_polymorphic([Manager, Engineer])
.order_by(Person.person_id)
- .join(pa, "paperwork")
+ .join(pa, Person.paperwork)
.filter(Person.name.like("%dog%"))
.filter(pa.description.like("%#2%"))
.all(),
@@ -606,7 +606,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess = fixture_session()
eq_(
sess.query(Company)
- .join("employees")
+ .join(Company.employees)
.filter(Person.name == "vlad")
.one(),
c2,
@@ -616,7 +616,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess = fixture_session()
eq_(
sess.query(Company)
- .join("employees", aliased=True)
+ .join(Company.employees, aliased=True)
.filter(Person.name == "vlad")
.one(),
c2,
@@ -627,7 +627,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
ea = aliased(Person)
eq_(
sess.query(Company)
- .join(ea, "employees")
+ .join(ea, Company.employees)
.filter(ea.name == "vlad")
.one(),
c2,
@@ -646,7 +646,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
any_ = Company.employees.any(Person.name == "wally")
eq_(
sess.query(Company)
- .join("employees", aliased=True)
+ .join(Company.employees, aliased=True)
.filter(Person.name == "dilbert")
.filter(any_)
.all(),
@@ -1172,7 +1172,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
ealias = aliased(Engineer)
eq_(
sess.query(Company)
- .join(ealias, "employees")
+ .join(ealias, Company.employees)
.filter(ealias.primary_language == "java")
.all(),
[c1],
@@ -1231,7 +1231,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess = fixture_session()
eq_(
sess.query(Company)
- .join("employees")
+ .join(Company.employees)
.filter(Engineer.primary_language == "java")
.all(),
[c1],
@@ -1264,7 +1264,10 @@ class _PolymorphicTestBase(fixtures.NoCache):
def test_join_to_subclass_fourteen(self):
sess = fixture_session()
eq_(
- sess.query(Company).join("employees", Engineer.machines).all(),
+ sess.query(Company)
+ .join(Company.employees)
+ .join(Engineer.machines)
+ .all(),
[c1, c2],
)
@@ -1272,7 +1275,8 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess = fixture_session()
eq_(
sess.query(Company)
- .join("employees", Engineer.machines)
+ .join(Company.employees)
+ .join(Engineer.machines)
.filter(Machine.name.ilike("%thinkpad%"))
.all(),
[c1],
@@ -1365,7 +1369,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess = fixture_session()
eq_(
sess.query(Company)
- .join("employees")
+ .join(Company.employees)
.filter(Person.name.in_(["dilbert", "vlad"]))
.join(Person.paperwork)
.filter(Paperwork.description.like("%#2%"))
@@ -1377,7 +1381,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
sess = fixture_session()
eq_(
sess.query(Company)
- .join("employees")
+ .join(Company.employees)
.filter(Person.name.in_(["dilbert", "vlad"]))
.join(Person.paperwork)
.filter(Paperwork.description.like("%#%"))
@@ -1445,7 +1449,7 @@ class _PolymorphicTestBase(fixtures.NoCache):
pa = aliased(Paperwork)
eq_(
sess.query(Company)
- .join(ea, "employees")
+ .join(ea, Company.employees)
.filter(ea.name.in_(["dilbert", "vlad"]))
.join(pa, ea.paperwork)
.filter(pa.description.like("%#2%"))
diff --git a/test/orm/inheritance/test_relationship.py b/test/orm/inheritance/test_relationship.py
index e795f0c7f..881353e3b 100644
--- a/test/orm/inheritance/test_relationship.py
+++ b/test/orm/inheritance/test_relationship.py
@@ -164,7 +164,7 @@ class SelfReferentialTestJoinedToBase(fixtures.MappedTest):
pa = aliased(Person)
eq_(
sess.query(Engineer)
- .join(pa, "reports_to")
+ .join(pa, Engineer.reports_to)
.filter(pa.name == "dogbert")
.first(),
Engineer(name="dilbert"),
@@ -276,7 +276,7 @@ class SelfReferentialJ2JTest(fixtures.MappedTest):
eq_(
sess.query(Engineer)
- .join(ma, "reports_to")
+ .join(ma, Engineer.reports_to)
.filter(ma.name == "dogbert")
.first(),
Engineer(name="dilbert"),
@@ -507,7 +507,7 @@ class SelfReferentialJ2JSelfTest(fixtures.MappedTest):
ea = aliased(Engineer)
eq_(
sess.query(Engineer)
- .join(ea, "reports_to")
+ .join(ea, Engineer.reports_to)
.filter(ea.name == "wally")
.first(),
Engineer(name="dilbert"),
@@ -937,7 +937,7 @@ class SelfReferentialM2MTest(fixtures.MappedTest, AssertsCompiledSQL):
# test that the splicing of the join works here, doesn't break in
# the middle of "parent join child1"
- q = sess.query(Child1).options(joinedload("left_child2"))
+ q = sess.query(Child1).options(joinedload(Child1.left_child2))
self.assert_compile(
q.limit(1).statement,
"SELECT child1.id, parent.id AS id_1, parent.cls, "
@@ -969,7 +969,7 @@ class SelfReferentialM2MTest(fixtures.MappedTest, AssertsCompiledSQL):
sess.flush()
sess.expunge_all()
- query_ = sess.query(Child1).options(subqueryload("left_child2"))
+ query_ = sess.query(Child1).options(subqueryload(Child1.left_child2))
for row in query_.all():
assert row.left_child2
@@ -1283,7 +1283,9 @@ class SubClassEagerToSubClassTest(fixtures.MappedTest):
def go():
eq_(
- sess.query(Subparent).options(joinedload("children")).all(),
+ sess.query(Subparent)
+ .options(joinedload(Subparent.children))
+ .all(),
[p1, p2],
)
@@ -1311,7 +1313,7 @@ class SubClassEagerToSubClassTest(fixtures.MappedTest):
eq_(
sess.query(Subparent)
.join(Subparent.children)
- .options(contains_eager("children"))
+ .options(contains_eager(Subparent.children))
.all(),
[p1, p2],
)
@@ -1337,7 +1339,9 @@ class SubClassEagerToSubClassTest(fixtures.MappedTest):
def go():
eq_(
- sess.query(Subparent).options(subqueryload("children")).all(),
+ sess.query(Subparent)
+ .options(subqueryload(Subparent.children))
+ .all(),
[p1, p2],
)
@@ -1770,7 +1774,8 @@ class SubClassToSubClassMultiTest(AssertsCompiledSQL, fixtures.MappedTest):
s = fixture_session()
self.assert_compile(
s.query(Parent)
- .join(Parent.sub1, Sub1.sub2)
+ .join(Parent.sub1)
+ .join(Sub1.sub2)
.join(Sub2.ep1)
.join(Sub2.ep2),
"SELECT parent.id AS parent_id, parent.data AS parent_data "
diff --git a/test/orm/inheritance/test_single.py b/test/orm/inheritance/test_single.py
index a3230f91d..690bdfc57 100644
--- a/test/orm/inheritance/test_single.py
+++ b/test/orm/inheritance/test_single.py
@@ -764,7 +764,7 @@ class RelationshipFromSingleTest(
sess = fixture_session()
with self.sql_execution_asserter(testing.db) as asserter:
- sess.query(Manager).options(subqueryload("stuff")).all()
+ sess.query(Manager).options(subqueryload(Manager.stuff)).all()
asserter.assert_(
CompiledSQL(
@@ -992,7 +992,7 @@ class RelationshipToSingleTest(
sess = fixture_session()
self.assert_compile(
- sess.query(Company, Engineer.name).outerjoin("engineers"),
+ sess.query(Company, Engineer.name).outerjoin(Company.engineers),
"SELECT companies.company_id AS companies_company_id, "
"companies.name AS companies_name, "
"employees.name AS employees_name "
@@ -1378,7 +1378,7 @@ class RelationshipToSingleTest(
sess.expunge_all()
eq_(
sess.query(Company)
- .options(joinedload("engineers"))
+ .options(joinedload(Company.engineers))
.order_by(Company.name)
.all(),
[
diff --git a/test/orm/test_ac_relationships.py b/test/orm/test_ac_relationships.py
index 26dd67480..6a050b698 100644
--- a/test/orm/test_ac_relationships.py
+++ b/test/orm/test_ac_relationships.py
@@ -49,7 +49,7 @@ class PartitionByFixture(fixtures.DeclarativeMappedTest):
.label("index"),
).alias()
- partitioned_b = cls.partitioned_b = aliased(B, alias=partition)
+ cls.partitioned_b = partitioned_b = aliased(B, alias=partition)
A.partitioned_bs = relationship(
partitioned_b,
@@ -141,7 +141,7 @@ class AliasedClassRelationshipTest(
self.assert_sql_count(testing.db, go, 2)
- @testing.combinations("string", "ac_attribute", "ac_attr_w_of_type")
+ @testing.combinations("ac_attribute", "ac_attr_w_of_type")
def test_selectinload_w_joinedload_after(self, calling_style):
"""test has been enhanced to also test #7224"""
@@ -151,9 +151,7 @@ class AliasedClassRelationshipTest(
partitioned_b = self.partitioned_b
- if calling_style == "string":
- opt = selectinload(A.partitioned_bs).joinedload("cs")
- elif calling_style == "ac_attribute":
+ if calling_style == "ac_attribute":
opt = selectinload(A.partitioned_bs).joinedload(partitioned_b.cs)
elif calling_style == "ac_attr_w_of_type":
# this would have been a workaround for people who encountered
diff --git a/test/orm/test_assorted_eager.py b/test/orm/test_assorted_eager.py
index 6f983e0ed..a97538da6 100644
--- a/test/orm/test_assorted_eager.py
+++ b/test/orm/test_assorted_eager.py
@@ -259,7 +259,7 @@ class EagerTest(fixtures.MappedTest):
)
s = fixture_session()
- q = s.query(Thing).options(sa.orm.joinedload("category"))
+ q = s.query(Thing).options(sa.orm.joinedload(Thing.category))
result = q.select_from(
tests.outerjoin(
@@ -292,7 +292,7 @@ class EagerTest(fixtures.MappedTest):
)
s = fixture_session()
- q = s.query(Thing).options(sa.orm.joinedload("category"))
+ q = s.query(Thing).options(sa.orm.joinedload(Thing.category))
result = q.filter(
sa.and_(
tests.c.owner_id == 1,
@@ -301,7 +301,7 @@ class EagerTest(fixtures.MappedTest):
options.c.someoption == False, # noqa
),
)
- ).outerjoin("owner_option")
+ ).outerjoin(Thing.owner_option)
result_str = ["%d %s" % (t.id, t.category.name) for t in result]
eq_(result_str, ["1 Some Category", "3 Some Category"])
@@ -311,13 +311,13 @@ class EagerTest(fixtures.MappedTest):
Thing, tests = (self.classes.Thing, self.tables.tests)
s = fixture_session()
- q = s.query(Thing).options(sa.orm.joinedload("category"))
+ q = s.query(Thing).options(sa.orm.joinedload(Thing.category))
result = q.filter(
(tests.c.owner_id == 1)
& text(
"options.someoption is null or options.someoption=:opt"
).bindparams(opt=False)
- ).join("owner_option")
+ ).join(Thing.owner_option)
result_str = ["%d %s" % (t.id, t.category.name) for t in result]
eq_(result_str, ["3 Some Category"])
@@ -330,14 +330,14 @@ class EagerTest(fixtures.MappedTest):
)
s = fixture_session()
- q = s.query(Thing).options(sa.orm.joinedload("category"))
+ q = s.query(Thing).options(sa.orm.joinedload(Thing.category))
result = q.filter(
(tests.c.owner_id == 1)
& (
(options.c.someoption == None)
| (options.c.someoption == False)
) # noqa
- ).join("owner_option")
+ ).join(Thing.owner_option)
result_str = ["%d %s" % (t.id, t.category.name) for t in result]
eq_(result_str, ["3 Some Category"])
@@ -552,7 +552,7 @@ class EagerTest3(fixtures.MappedTest):
# "order by max desc" separately
q = (
session.query(Data)
- .options(sa.orm.joinedload("foo"))
+ .options(sa.orm.joinedload(Data.foo))
.select_from(
datas.join(arb_data, arb_data.c.data_id == datas.c.id)
)
@@ -639,7 +639,7 @@ class EagerTest4(fixtures.MappedTest):
q = (
sess.query(Department)
- .join("employees")
+ .join(Department.employees)
.filter(Employee.name.startswith("J"))
.distinct()
.order_by(sa.desc(Department.name))
@@ -1317,10 +1317,10 @@ class EagerTest9(fixtures.MappedTest):
acc = (
session.query(Account)
.options(
- sa.orm.joinedload("entries")
- .joinedload("transaction")
- .joinedload("entries")
- .joinedload("account")
+ sa.orm.joinedload(Account.entries)
+ .joinedload(Entry.transaction)
+ .joinedload(Transaction.entries)
+ .joinedload(Entry.account)
)
.order_by(Account.account_id)
).first()
diff --git a/test/orm/test_cache_key.py b/test/orm/test_cache_key.py
index f25a57fe5..d689bd6ba 100644
--- a/test/orm/test_cache_key.py
+++ b/test/orm/test_cache_key.py
@@ -249,6 +249,8 @@ class CacheKeyTest(CacheKeyFixture, _fixtures.FixtureTest):
"User", "Address", "Keyword", "Order", "Item"
)
+ a1 = aliased(Address)
+
self._run_cache_key_fixture(
lambda: (
Load(User).joinedload(User.addresses),
@@ -261,10 +263,10 @@ class CacheKeyTest(CacheKeyFixture, _fixtures.FixtureTest):
User.orders.and_(Order.description != "somename")
),
Load(User).defer(User.id),
- Load(User).subqueryload("addresses"),
- Load(Address).defer("id"),
+ Load(User).subqueryload(User.addresses),
+ Load(Address).defer(Address.id),
Load(Address).defer("*"),
- Load(aliased(Address)).defer("id"),
+ Load(a1).defer(a1.id),
Load(User).joinedload(User.addresses).defer(Address.id),
Load(User).joinedload(User.orders).joinedload(Order.items),
Load(User).joinedload(User.orders).subqueryload(Order.items),
@@ -276,33 +278,11 @@ class CacheKeyTest(CacheKeyFixture, _fixtures.FixtureTest):
Load(User).defaultload(User.orders).defaultload(Order.items),
Load(User).defaultload(User.orders),
Load(Address).raiseload("*"),
- Load(Address).raiseload("user"),
+ Load(Address).raiseload(Address.user),
),
compare_values=True,
)
- def test_bound_options_equiv_on_strname(self):
- """Bound loader options resolve on string name so test that the cache
- key for the string version matches the resolved version.
-
- """
- User, Address, Keyword, Order, Item = self.classes(
- "User", "Address", "Keyword", "Order", "Item"
- )
-
- for left, right in [
- (Load(User).defer(User.id), Load(User).defer("id")),
- (
- Load(User).joinedload(User.addresses),
- Load(User).joinedload("addresses"),
- ),
- (
- Load(User).joinedload(User.orders).joinedload(Order.items),
- Load(User).joinedload("orders").joinedload("items"),
- ),
- ]:
- eq_(left._generate_cache_key(), right._generate_cache_key())
-
def test_selects_w_orm_joins(self):
User, Address, Keyword, Order, Item = self.classes(
@@ -353,16 +333,10 @@ class CacheKeyTest(CacheKeyFixture, _fixtures.FixtureTest):
.join(User.orders),
fixture_session()
.query(User)
- .join("addresses")
- .join("dingalings", from_joinpoint=True),
- fixture_session().query(User).join("addresses"),
- fixture_session().query(User).join("orders"),
- fixture_session().query(User).join("addresses").join("orders"),
+ .join(User.addresses)
+ .join(Address.dingaling),
fixture_session().query(User).join(Address, User.addresses),
- fixture_session().query(User).join(a1, "addresses"),
- fixture_session()
- .query(User)
- .join(a1, "addresses", aliased=True),
+ fixture_session().query(User).join(a1, User.addresses),
fixture_session().query(User).join(User.addresses.of_type(a1)),
),
compare_values=True,
diff --git a/test/orm/test_composites.py b/test/orm/test_composites.py
index 4bdca7a45..1dc139df9 100644
--- a/test/orm/test_composites.py
+++ b/test/orm/test_composites.py
@@ -179,7 +179,9 @@ class PointTest(fixtures.MappedTest, testing.AssertsCompiledSQL):
def go():
g2 = (
- sess.query(Graph).options(sa.orm.joinedload("edges")).get(g.id)
+ sess.query(Graph)
+ .options(sa.orm.joinedload(Graph.edges))
+ .get(g.id)
)
eq_(
diff --git a/test/orm/test_default_strategies.py b/test/orm/test_default_strategies.py
index 249a446ea..9b228bbaa 100644
--- a/test/orm/test_default_strategies.py
+++ b/test/orm/test_default_strategies.py
@@ -1,7 +1,10 @@
import sqlalchemy as sa
from sqlalchemy import testing
from sqlalchemy import util
+from sqlalchemy.orm import defaultload
+from sqlalchemy.orm import joinedload
from sqlalchemy.orm import relationship
+from sqlalchemy.orm import subqueryload
from sqlalchemy.testing import assert_raises_message
from sqlalchemy.testing import eq_
from sqlalchemy.testing.fixtures import fixture_session
@@ -239,8 +242,8 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
def go():
users[:] = (
sess.query(self.classes.User)
- .options(sa.orm.subqueryload("*"))
- .options(sa.orm.joinedload(self.classes.User.addresses))
+ .options(subqueryload("*"))
+ .options(joinedload(self.classes.User.addresses))
.options(sa.orm.lazyload("*"))
.order_by(self.classes.User.id)
.all()
@@ -254,7 +257,7 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
def test_star_must_be_alone(self):
sess = self._downgrade_fixture()
User = self.classes.User
- opt = sa.orm.subqueryload("*", User.addresses)
+ opt = subqueryload("*", User.addresses)
assert_raises_message(
sa.exc.ArgumentError,
"Wildcard token cannot be followed by another entity",
@@ -287,7 +290,7 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
users[:] = (
sess.query(self.classes.User)
.options(sa.orm.lazyload("*"))
- .options(sa.orm.joinedload(self.classes.User.addresses))
+ .options(joinedload(self.classes.User.addresses))
.order_by(self.classes.User.id)
.all()
)
@@ -317,7 +320,7 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
users[:] = (
sess.query(self.classes.User)
.options(sa.orm.lazyload("*"))
- .options(sa.orm.subqueryload(self.classes.User.orders))
+ .options(subqueryload(self.classes.User.orders))
.order_by(self.classes.User.id)
.all()
)
@@ -355,7 +358,7 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
users[:] = (
sess.query(self.classes.User)
.options(sa.orm.noload("*"))
- .options(sa.orm.joinedload(self.classes.User.addresses))
+ .options(joinedload(self.classes.User.addresses))
.order_by(self.classes.User.id)
.all()
)
@@ -385,7 +388,7 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
users[:] = (
sess.query(self.classes.User)
.options(sa.orm.noload("*"))
- .options(sa.orm.subqueryload(self.classes.User.orders))
+ .options(subqueryload(self.classes.User.orders))
.order_by(self.classes.User.id)
.all()
)
@@ -414,7 +417,7 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
def go():
users[:] = (
sess.query(self.classes.User)
- .options(sa.orm.joinedload("*"))
+ .options(joinedload("*"))
.order_by(self.classes.User.id)
.all()
)
@@ -428,14 +431,20 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
sess = self._upgrade_fixture()
users = []
+ User, Order, Item = self.classes("User", "Order", "Item")
+
# test upgrade all to joined: 1 sql
def go():
users[:] = (
- sess.query(self.classes.User)
- .options(sa.orm.joinedload(".*"))
- .options(sa.orm.joinedload("addresses.*"))
- .options(sa.orm.joinedload("orders.*"))
- .options(sa.orm.joinedload("orders.items.*"))
+ sess.query(User)
+ .options(joinedload(".*"))
+ .options(defaultload(User.addresses).joinedload("*"))
+ .options(defaultload(User.orders).joinedload("*"))
+ .options(
+ defaultload(User.orders)
+ .defaultload(Order.items)
+ .joinedload("*")
+ )
.order_by(self.classes.User.id)
.all()
)
@@ -450,13 +459,19 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
sess = self._upgrade_fixture()
users = []
+ User, Order, Item = self.classes("User", "Order", "Item")
+
# test joined all but 'keywords': upgraded to 1 sql
def go():
users[:] = (
- sess.query(self.classes.User)
- .options(sa.orm.lazyload("orders.items.keywords"))
- .options(sa.orm.joinedload("*"))
- .order_by(self.classes.User.id)
+ sess.query(User)
+ .options(
+ defaultload(User.orders)
+ .defaultload(Order.items)
+ .lazyload(Item.keywords)
+ )
+ .options(joinedload("*"))
+ .order_by(User.id)
.all()
)
@@ -492,8 +507,8 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
def go():
users[:] = (
sess.query(self.classes.User)
- .options(sa.orm.subqueryload(self.classes.User.addresses))
- .options(sa.orm.joinedload("*"))
+ .options(subqueryload(self.classes.User.addresses))
+ .options(joinedload("*"))
.order_by(self.classes.User.id)
.all()
)
@@ -513,7 +528,7 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
def go():
users[:] = (
sess.query(self.classes.User)
- .options(sa.orm.subqueryload("*"))
+ .options(subqueryload("*"))
.order_by(self.classes.User.id)
.all()
)
@@ -527,15 +542,21 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
sess = self._upgrade_fixture()
users = []
+ User, Order = self.classes("User", "Order")
+
# test upgrade all to subquery: 1 sql + 4 relationships = 5
def go():
users[:] = (
- sess.query(self.classes.User)
- .options(sa.orm.subqueryload(".*"))
- .options(sa.orm.subqueryload("addresses.*"))
- .options(sa.orm.subqueryload("orders.*"))
- .options(sa.orm.subqueryload("orders.items.*"))
- .order_by(self.classes.User.id)
+ sess.query(User)
+ .options(subqueryload(".*"))
+ .options(defaultload(User.addresses).subqueryload("*"))
+ .options(defaultload(User.orders).subqueryload("*"))
+ .options(
+ defaultload(User.orders)
+ .defaultload(Order.items)
+ .subqueryload("*")
+ )
+ .order_by(User.id)
.all()
)
@@ -550,14 +571,19 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
is still honored"""
sess = self._upgrade_fixture()
users = []
+ User, Order, Item = self.classes("User", "Order", "Item")
# test subquery all but 'keywords' (1 sql + 3 relationships = 4)
def go():
users[:] = (
- sess.query(self.classes.User)
- .options(sa.orm.lazyload("orders.items.keywords"))
- .options(sa.orm.subqueryload("*"))
- .order_by(self.classes.User.id)
+ sess.query(User)
+ .options(
+ defaultload(User.orders)
+ .defaultload(Order.items)
+ .lazyload(Item.keywords)
+ )
+ .options(subqueryload("*"))
+ .order_by(User.id)
.all()
)
@@ -593,9 +619,9 @@ class DefaultStrategyOptionsTest(_fixtures.FixtureTest):
def go():
users[:] = (
sess.query(self.classes.User)
- .options(sa.orm.joinedload(self.classes.User.addresses))
- .options(sa.orm.joinedload(self.classes.User.orders))
- .options(sa.orm.subqueryload("*"))
+ .options(joinedload(self.classes.User.addresses))
+ .options(joinedload(self.classes.User.orders))
+ .options(subqueryload("*"))
.order_by(self.classes.User.id)
.all()
)
@@ -661,7 +687,7 @@ class NoLoadTest(_fixtures.FixtureTest):
)
),
)
- q = fixture_session().query(m).options(sa.orm.lazyload("addresses"))
+ q = fixture_session().query(m).options(sa.orm.lazyload(User.addresses))
result = [None]
def go():
@@ -690,7 +716,7 @@ class NoLoadTest(_fixtures.FixtureTest):
a1 = (
s.query(Address)
.filter_by(id=1)
- .options(sa.orm.noload("user"))
+ .options(sa.orm.noload(Address.user))
.first()
)
diff --git a/test/orm/test_deferred.py b/test/orm/test_deferred.py
index 9f9068783..e44d6ec86 100644
--- a/test/orm/test_deferred.py
+++ b/test/orm/test_deferred.py
@@ -370,7 +370,7 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
self.mapper_registry.map_imperatively(Order, orders)
sess = fixture_session()
- q = sess.query(Order).order_by(Order.id).options(defer("user_id"))
+ q = sess.query(Order).order_by(Order.id).options(defer(Order.user_id))
def go():
q.all()[0].user_id
@@ -395,7 +395,7 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
)
sess.expunge_all()
- q2 = q.options(undefer("user_id"))
+ q2 = q.options(undefer(Order.user_id))
self.sql_eq_(
q2.all,
[
@@ -985,7 +985,11 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
eq_(item.description, "item 4")
sess.expunge_all()
- result = q.options(undefer("orders.items.description")).all()
+ result = q.options(
+ defaultload(User.orders)
+ .defaultload(Order.items)
+ .undefer(Item.description)
+ ).all()
item = result[0].orders[1].items[1]
def go():
@@ -1055,7 +1059,9 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
sess = fixture_session()
q = sess.query(User).options(
- joinedload(User.orders).defer("description").defer("isopen")
+ joinedload(User.orders)
+ .defer(Order.description)
+ .defer(Order.isopen)
)
self.assert_compile(
q,
@@ -1075,7 +1081,9 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
self.mapper_registry.map_imperatively(Order, orders)
sess = fixture_session()
- q = sess.query(Order).options(load_only("isopen", "description"))
+ q = sess.query(Order).options(
+ load_only(Order.isopen, Order.description)
+ )
self.assert_compile(
q,
"SELECT orders.id AS orders_id, "
@@ -1092,7 +1100,7 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
q = (
sess.query(Order)
.order_by(Order.id)
- .options(load_only("isopen", "description"))
+ .options(load_only(Order.isopen, Order.description))
)
eq_(q.first(), Order(id=1))
@@ -1107,7 +1115,7 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
sess = fixture_session()
q = sess.query(Order).options(
- load_only("isopen", "description"), undefer("user_id")
+ load_only(Order.isopen, Order.description), undefer(Order.user_id)
)
self.assert_compile(
q,
@@ -1117,8 +1125,7 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
"orders.isopen AS orders_isopen FROM orders",
)
- @testing.combinations(("string",), ("attr",))
- def test_load_only_synonym(self, type_):
+ def test_load_only_synonym(self):
orders, Order = self.tables.orders, self.classes.Order
self.mapper_registry.map_imperatively(
@@ -1127,10 +1134,7 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
properties={"desc": synonym("description")},
)
- if type_ == "attr":
- opt = load_only(Order.isopen, Order.desc)
- else:
- opt = load_only("isopen", "desc")
+ opt = load_only(Order.isopen, Order.desc)
sess = fixture_session()
q = sess.query(Order).options(opt)
@@ -1184,10 +1188,12 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
opt = (
Load(User)
.defaultload(User.addresses)
- .load_only("id", "email_address")
+ .load_only(Address.id, Address.email_address)
)
else:
- opt = defaultload(User.addresses).load_only("id", "email_address")
+ opt = defaultload(User.addresses).load_only(
+ Address.id, Address.email_address
+ )
q = sess.query(User).options(opt).filter(User.id.in_([7, 8]))
def go():
@@ -1211,9 +1217,9 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
sess = fixture_session()
q = sess.query(User, Order, Address).options(
- Load(User).load_only("name"),
- Load(Order).load_only("id"),
- Load(Address).load_only("id", "email_address"),
+ Load(User).load_only(User.name),
+ Load(Order).load_only(Order.id),
+ Load(Address).load_only(Address.id, Address.email_address),
)
self.assert_compile(
@@ -1252,10 +1258,10 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
sess = fixture_session()
q = sess.query(User).options(
- load_only("name")
- .defaultload("addresses")
- .load_only("id", "email_address"),
- defaultload("orders").load_only("id"),
+ load_only(User.name)
+ .defaultload(User.addresses)
+ .load_only(Address.id, Address.email_address),
+ defaultload(User.orders).load_only(Order.id),
)
# hmmmm joinedload seems to be forcing users.id into here...
@@ -1339,7 +1345,7 @@ class InheritanceTest(_Polymorphic):
q = (
s.query(Manager)
.order_by(Manager.person_id)
- .options(load_only("status", "manager_name"))
+ .options(load_only(Manager.status, Manager.manager_name))
)
self.assert_compile(
q,
@@ -1358,7 +1364,9 @@ class InheritanceTest(_Polymorphic):
q = (
s.query(Manager)
.order_by(Manager.person_id)
- .options(Load(Manager).load_only("status", "manager_name"))
+ .options(
+ Load(Manager).load_only(Manager.status, Manager.manager_name)
+ )
)
self.assert_compile(
q,
@@ -1377,7 +1385,7 @@ class InheritanceTest(_Polymorphic):
q = (
s.query(Boss)
.order_by(Person.person_id)
- .options(load_only("status", "manager_name"))
+ .options(load_only(Boss.status, Boss.manager_name))
)
self.assert_compile(
q,
@@ -1396,7 +1404,7 @@ class InheritanceTest(_Polymorphic):
q = (
s.query(Boss)
.order_by(Person.person_id)
- .options(Load(Boss).load_only("status", "manager_name"))
+ .options(Load(Boss).load_only(Boss.status, Manager.manager_name))
)
self.assert_compile(
q,
@@ -1416,7 +1424,7 @@ class InheritanceTest(_Polymorphic):
q = (
s.query(m1)
.order_by(m1.person_id)
- .options(load_only("status", "manager_name"))
+ .options(load_only(m1.status, m1.manager_name))
)
self.assert_compile(
q,
@@ -1436,7 +1444,7 @@ class InheritanceTest(_Polymorphic):
q = (
s.query(m1)
.order_by(m1.person_id)
- .options(Load(m1).load_only("status", "manager_name"))
+ .options(Load(m1).load_only(m1.status, m1.manager_name))
)
self.assert_compile(
q,
@@ -1511,7 +1519,7 @@ class InheritanceTest(_Polymorphic):
.join(Company.managers)
.options(
contains_eager(Company.managers).load_only(
- "status", "manager_name"
+ Manager.status, Manager.manager_name
)
)
)
@@ -1536,7 +1544,7 @@ class InheritanceTest(_Polymorphic):
.options(
Load(Company)
.contains_eager(Company.managers)
- .load_only("status", "manager_name")
+ .load_only(Manager.status, Manager.manager_name)
)
)
self.assert_compile(
@@ -1562,7 +1570,7 @@ class InheritanceTest(_Polymorphic):
q = (
s.query(Manager)
.order_by(Person.person_id)
- .options(defer(".*"), undefer("status"))
+ .options(defer(".*"), undefer(Manager.status))
)
self.assert_compile(
q,
@@ -1577,7 +1585,9 @@ class InheritanceTest(_Polymorphic):
def test_load_only_subclass_of_type(self):
s = fixture_session()
q = s.query(Company).options(
- joinedload(Company.employees.of_type(Manager)).load_only("status")
+ joinedload(Company.employees.of_type(Manager)).load_only(
+ Manager.status
+ )
)
self.assert_compile(
q,
@@ -1624,7 +1634,11 @@ class InheritanceTest(_Polymorphic):
def test_defer_super_name_on_subclass(self):
s = fixture_session()
- q = s.query(Manager).order_by(Person.person_id).options(defer("name"))
+ q = (
+ s.query(Manager)
+ .order_by(Person.person_id)
+ .options(defer(Person.name))
+ )
self.assert_compile(
q,
"SELECT managers.person_id AS managers_person_id, "
@@ -1642,7 +1656,7 @@ class InheritanceTest(_Polymorphic):
q = (
s.query(Manager)
.order_by(Person.person_id)
- .options(Load(Manager).defer("name"))
+ .options(Load(Manager).defer(Manager.name))
)
self.assert_compile(
q,
@@ -1686,19 +1700,6 @@ class InheritanceTest(_Polymorphic):
wp = with_polymorphic(Person, [Manager], flat=True)
- # needs to be explicit, we don't currently dig onto all the
- # sub-entities in the wp
- assert_raises_message(
- sa.exc.ArgumentError,
- r'Can\'t find property named "status" on '
- r"with_polymorphic\(Person, \[Manager\]\) in this Query.",
- s.query(Company)
- .options(
- joinedload(Company.employees.of_type(wp)).load_only("status")
- )
- ._compile_context,
- )
-
assert_raises_message(
sa.exc.ArgumentError,
'Attribute "Manager.status" does not link from element '
@@ -2225,7 +2226,9 @@ class DeferredPopulationTest(fixtures.MappedTest):
Thing = self.classes.Thing
session = fixture_session()
- thing = session.query(Thing).options(sa.orm.undefer("name")).first()
+ thing = (
+ session.query(Thing).options(sa.orm.undefer(Thing.name)).first()
+ )
self._test(thing)
def test_query_twice_with_clear(self):
@@ -2234,7 +2237,9 @@ class DeferredPopulationTest(fixtures.MappedTest):
session = fixture_session()
result = session.query(Thing).first() # noqa
session.expunge_all()
- thing = session.query(Thing).options(sa.orm.undefer("name")).first()
+ thing = (
+ session.query(Thing).options(sa.orm.undefer(Thing.name)).first()
+ )
self._test(thing)
def test_query_twice_no_clear(self):
@@ -2242,7 +2247,9 @@ class DeferredPopulationTest(fixtures.MappedTest):
session = fixture_session()
result = session.query(Thing).first() # noqa
- thing = session.query(Thing).options(sa.orm.undefer("name")).first()
+ thing = (
+ session.query(Thing).options(sa.orm.undefer(Thing.name)).first()
+ )
self._test(thing)
def test_joinedload_with_clear(self):
@@ -2250,10 +2257,14 @@ class DeferredPopulationTest(fixtures.MappedTest):
session = fixture_session()
human = ( # noqa
- session.query(Human).options(sa.orm.joinedload("thing")).first()
+ session.query(Human)
+ .options(sa.orm.joinedload(Human.thing))
+ .first()
)
session.expunge_all()
- thing = session.query(Thing).options(sa.orm.undefer("name")).first()
+ thing = (
+ session.query(Thing).options(sa.orm.undefer(Thing.name)).first()
+ )
self._test(thing)
def test_joinedload_no_clear(self):
@@ -2261,9 +2272,13 @@ class DeferredPopulationTest(fixtures.MappedTest):
session = fixture_session()
human = ( # noqa
- session.query(Human).options(sa.orm.joinedload("thing")).first()
+ session.query(Human)
+ .options(sa.orm.joinedload(Human.thing))
+ .first()
+ )
+ thing = (
+ session.query(Thing).options(sa.orm.undefer(Thing.name)).first()
)
- thing = session.query(Thing).options(sa.orm.undefer("name")).first()
self._test(thing)
def test_join_with_clear(self):
@@ -2271,10 +2286,12 @@ class DeferredPopulationTest(fixtures.MappedTest):
session = fixture_session()
result = ( # noqa
- session.query(Human).add_entity(Thing).join("thing").first()
+ session.query(Human).add_entity(Thing).join(Human.thing).first()
)
session.expunge_all()
- thing = session.query(Thing).options(sa.orm.undefer("name")).first()
+ thing = (
+ session.query(Thing).options(sa.orm.undefer(Thing.name)).first()
+ )
self._test(thing)
def test_join_no_clear(self):
@@ -2282,7 +2299,9 @@ class DeferredPopulationTest(fixtures.MappedTest):
session = fixture_session()
result = ( # noqa
- session.query(Human).add_entity(Thing).join("thing").first()
+ session.query(Human).add_entity(Thing).join(Human.thing).first()
+ )
+ thing = (
+ session.query(Thing).options(sa.orm.undefer(Thing.name)).first()
)
- thing = session.query(Thing).options(sa.orm.undefer("name")).first()
self._test(thing)
diff --git a/test/orm/test_deprecations.py b/test/orm/test_deprecations.py
index ddfad7e0f..2ab45827b 100644
--- a/test/orm/test_deprecations.py
+++ b/test/orm/test_deprecations.py
@@ -7,6 +7,7 @@ from sqlalchemy import event
from sqlalchemy import exc as sa_exc
from sqlalchemy import ForeignKey
from sqlalchemy import func
+from sqlalchemy import inspect
from sqlalchemy import Integer
from sqlalchemy import literal_column
from sqlalchemy import MetaData
@@ -31,18 +32,24 @@ from sqlalchemy.orm import contains_alias
from sqlalchemy.orm import contains_eager
from sqlalchemy.orm import declarative_base
from sqlalchemy.orm import declared_attr
+from sqlalchemy.orm import defaultload
from sqlalchemy.orm import defer
from sqlalchemy.orm import deferred
from sqlalchemy.orm import eagerload
+from sqlalchemy.orm import exc as orm_exc
from sqlalchemy.orm import foreign
from sqlalchemy.orm import instrumentation
from sqlalchemy.orm import joinedload
+from sqlalchemy.orm import Load
+from sqlalchemy.orm import load_only
from sqlalchemy.orm import mapper
from sqlalchemy.orm import relation
from sqlalchemy.orm import relationship
from sqlalchemy.orm import scoped_session
+from sqlalchemy.orm import selectinload
from sqlalchemy.orm import Session
from sqlalchemy.orm import sessionmaker
+from sqlalchemy.orm import strategy_options
from sqlalchemy.orm import subqueryload
from sqlalchemy.orm import synonym
from sqlalchemy.orm import undefer
@@ -70,14 +77,22 @@ from sqlalchemy.testing.mock import call
from sqlalchemy.testing.mock import Mock
from sqlalchemy.testing.schema import Column
from sqlalchemy.testing.schema import Table
+from sqlalchemy.util import pickle
from . import _fixtures
from .inheritance import _poly_fixtures
+from .inheritance._poly_fixtures import _Polymorphic
+from .inheritance._poly_fixtures import Company
+from .inheritance._poly_fixtures import Engineer
+from .test_ac_relationships import PartitionByFixture
from .test_bind import GetBindTest as _GetBindTest
from .test_dynamic import _DynamicFixture
from .test_events import _RemoveListeners
from .test_options import PathTest as OptionsPathTest
+from .test_options import PathTest
+from .test_options import QueryTest as OptionsQueryTest
from .test_query import QueryTest
from .test_transaction import _LocalFixture
+from ..sql.test_compare import CacheKeyFixture
join_aliased_dep = (
@@ -94,12 +109,27 @@ join_chain_dep = (
r"Passing a chain of multiple join conditions to Query.join\(\)"
)
+undefer_needs_chaining = (
+ r"The \*addl_attrs on orm.(?:un)?defer is deprecated. "
+ "Please use method chaining"
+)
+
join_strings_dep = "Using strings to indicate relationship names in Query.join"
join_tuple_form = (
r"Query.join\(\) will no longer accept tuples as "
"arguments in SQLAlchemy 2.0."
)
+opt_strings_dep = (
+ "Using strings to indicate column or relationship "
+ "paths in loader options"
+)
+
+wparent_strings_dep = (
+ r"Using strings to indicate relationship names "
+ r"in the ORM with_parent\(\) function"
+)
+
def _aliased_join_warning(arg=None):
return testing.expect_warnings(
@@ -115,6 +145,337 @@ def _aliased_join_deprecation(arg=None):
)
+class CustomJoinTest(QueryTest):
+ run_setup_mappers = None
+
+ def test_double_same_mappers_flag_alias(self):
+ """test aliasing of joins with a custom join condition"""
+
+ (
+ addresses,
+ items,
+ order_items,
+ orders,
+ Item,
+ User,
+ Address,
+ Order,
+ users,
+ ) = (
+ self.tables.addresses,
+ self.tables.items,
+ self.tables.order_items,
+ self.tables.orders,
+ self.classes.Item,
+ self.classes.User,
+ self.classes.Address,
+ self.classes.Order,
+ self.tables.users,
+ )
+
+ self.mapper_registry.map_imperatively(Address, addresses)
+ self.mapper_registry.map_imperatively(
+ Order,
+ orders,
+ properties={
+ "items": relationship(
+ Item,
+ secondary=order_items,
+ lazy="select",
+ order_by=items.c.id,
+ )
+ },
+ )
+ self.mapper_registry.map_imperatively(Item, items)
+ self.mapper_registry.map_imperatively(
+ User,
+ users,
+ properties=dict(
+ addresses=relationship(Address, lazy="select"),
+ open_orders=relationship(
+ Order,
+ primaryjoin=and_(
+ orders.c.isopen == 1, users.c.id == orders.c.user_id
+ ),
+ lazy="select",
+ viewonly=True,
+ ),
+ closed_orders=relationship(
+ Order,
+ primaryjoin=and_(
+ orders.c.isopen == 0, users.c.id == orders.c.user_id
+ ),
+ lazy="select",
+ viewonly=True,
+ ),
+ ),
+ )
+ q = fixture_session().query(User)
+
+ with assertions.expect_deprecated_20(
+ join_aliased_dep,
+ join_strings_dep,
+ join_chain_dep,
+ raise_on_any_unexpected=True,
+ ):
+ eq_(
+ q.join("open_orders", "items", aliased=True)
+ .filter(Item.id == 4)
+ .join("closed_orders", "items", aliased=True)
+ .filter(Item.id == 3)
+ .all(),
+ [User(id=7)],
+ )
+
+
+class PickleTest(fixtures.MappedTest):
+ @classmethod
+ def define_tables(cls, metadata):
+ Table(
+ "users",
+ metadata,
+ Column(
+ "id", Integer, primary_key=True, test_needs_autoincrement=True
+ ),
+ Column("name", String(30), nullable=False),
+ test_needs_acid=True,
+ test_needs_fk=True,
+ )
+
+ Table(
+ "addresses",
+ metadata,
+ Column(
+ "id", Integer, primary_key=True, test_needs_autoincrement=True
+ ),
+ Column("user_id", None, ForeignKey("users.id")),
+ Column("email_address", String(50), nullable=False),
+ test_needs_acid=True,
+ test_needs_fk=True,
+ )
+ Table(
+ "orders",
+ metadata,
+ Column(
+ "id", Integer, primary_key=True, test_needs_autoincrement=True
+ ),
+ Column("user_id", None, ForeignKey("users.id")),
+ Column("address_id", None, ForeignKey("addresses.id")),
+ Column("description", String(30)),
+ Column("isopen", Integer),
+ test_needs_acid=True,
+ test_needs_fk=True,
+ )
+ Table(
+ "dingalings",
+ metadata,
+ Column(
+ "id", Integer, primary_key=True, test_needs_autoincrement=True
+ ),
+ Column("address_id", None, ForeignKey("addresses.id")),
+ Column("data", String(30)),
+ test_needs_acid=True,
+ test_needs_fk=True,
+ )
+
+ def _option_test_fixture(self):
+ users, addresses, dingalings = (
+ self.tables.users,
+ self.tables.addresses,
+ self.tables.dingalings,
+ )
+
+ # these must be module level for pickling
+ from .test_pickled import User, Address, Dingaling
+
+ self.mapper_registry.map_imperatively(
+ User,
+ users,
+ properties={"addresses": relationship(Address, backref="user")},
+ )
+ self.mapper_registry.map_imperatively(
+ Address,
+ addresses,
+ properties={"dingaling": relationship(Dingaling)},
+ )
+ self.mapper_registry.map_imperatively(Dingaling, dingalings)
+ sess = fixture_session()
+ u1 = User(name="ed")
+ u1.addresses.append(Address(email_address="ed@bar.com"))
+ sess.add(u1)
+ sess.flush()
+ sess.expunge_all()
+ return sess, User, Address, Dingaling
+
+ @testing.requires.non_broken_pickle
+ def test_became_bound_options(self):
+ sess, User, Address, Dingaling = self._option_test_fixture()
+
+ for opt in [
+ sa.orm.joinedload("addresses"),
+ sa.orm.defer("name"),
+ sa.orm.joinedload("addresses").joinedload(Address.dingaling),
+ ]:
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ context = sess.query(User).options(opt)._compile_context()
+ opt = [
+ v
+ for v in context.attributes.values()
+ if isinstance(v, sa.orm.Load)
+ ][0]
+
+ opt2 = pickle.loads(pickle.dumps(opt))
+ eq_(opt.path, opt2.path)
+ eq_(opt.local_opts, opt2.local_opts)
+
+ u1 = sess.query(User).options(opt).first()
+ pickle.loads(pickle.dumps(u1))
+
+ @testing.requires.non_broken_pickle
+ @testing.combinations(
+ lambda: sa.orm.joinedload("addresses"),
+ lambda: sa.orm.defer("name"),
+ lambda Address: sa.orm.joinedload("addresses").joinedload(
+ Address.dingaling
+ ),
+ lambda: sa.orm.joinedload("addresses").raiseload("*"),
+ )
+ def test_unbound_options(self, test_case):
+ sess, User, Address, Dingaling = self._option_test_fixture()
+
+ opt = testing.resolve_lambda(test_case, User=User, Address=Address)
+ opt2 = pickle.loads(pickle.dumps(opt))
+ eq_(opt.path, opt2.path)
+
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ u1 = sess.query(User).options(opt).first()
+ pickle.loads(pickle.dumps(u1))
+
+ @testing.requires.non_broken_pickle
+ @testing.combinations(
+ lambda User: sa.orm.Load(User).joinedload("addresses"),
+ lambda User: sa.orm.Load(User).joinedload("addresses").raiseload("*"),
+ lambda User: sa.orm.Load(User).defer("name"),
+ lambda User, Address: sa.orm.Load(User)
+ .joinedload("addresses")
+ .joinedload(Address.dingaling),
+ lambda User, Address: sa.orm.Load(User)
+ .joinedload("addresses", innerjoin=True)
+ .joinedload(Address.dingaling),
+ )
+ def test_bound_options(self, test_case):
+ sess, User, Address, Dingaling = self._option_test_fixture()
+
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ opt = testing.resolve_lambda(test_case, User=User, Address=Address)
+
+ opt2 = pickle.loads(pickle.dumps(opt))
+ eq_(opt.path, opt2.path)
+ eq_(opt.context.keys(), opt2.context.keys())
+ eq_(opt.local_opts, opt2.local_opts)
+
+ u1 = sess.query(User).options(opt).first()
+ pickle.loads(pickle.dumps(u1))
+
+
+class SynonymTest(QueryTest, AssertsCompiledSQL):
+ __dialect__ = "default"
+
+ @classmethod
+ def setup_mappers(cls):
+ (
+ users,
+ Keyword,
+ items,
+ order_items,
+ orders,
+ Item,
+ User,
+ Address,
+ keywords,
+ Order,
+ item_keywords,
+ addresses,
+ ) = (
+ cls.tables.users,
+ cls.classes.Keyword,
+ cls.tables.items,
+ cls.tables.order_items,
+ cls.tables.orders,
+ cls.classes.Item,
+ cls.classes.User,
+ cls.classes.Address,
+ cls.tables.keywords,
+ cls.classes.Order,
+ cls.tables.item_keywords,
+ cls.tables.addresses,
+ )
+
+ cls.mapper_registry.map_imperatively(
+ User,
+ users,
+ properties={
+ "name_syn": synonym("name"),
+ "addresses": relationship(Address),
+ "orders": relationship(
+ Order, backref="user", order_by=orders.c.id
+ ), # o2m, m2o
+ "orders_syn": synonym("orders"),
+ "orders_syn_2": synonym("orders_syn"),
+ },
+ )
+ cls.mapper_registry.map_imperatively(Address, addresses)
+ cls.mapper_registry.map_imperatively(
+ Order,
+ orders,
+ properties={
+ "items": relationship(Item, secondary=order_items), # m2m
+ "address": relationship(Address), # m2o
+ "items_syn": synonym("items"),
+ },
+ )
+ cls.mapper_registry.map_imperatively(
+ Item,
+ items,
+ properties={
+ "keywords": relationship(
+ Keyword, secondary=item_keywords
+ ) # m2m
+ },
+ )
+ cls.mapper_registry.map_imperatively(Keyword, keywords)
+
+ def test_options_syn_of_syn_string(self):
+ User, Order = self.classes.User, self.classes.Order
+
+ s = fixture_session()
+
+ def go():
+ with testing.expect_deprecated_20(opt_strings_dep):
+ result = (
+ s.query(User)
+ .filter_by(name="jack")
+ .options(joinedload("orders_syn_2"))
+ .all()
+ )
+ eq_(
+ result,
+ [
+ User(
+ id=7,
+ name="jack",
+ orders=[
+ Order(description="order 1"),
+ Order(description="order 3"),
+ Order(description="order 5"),
+ ],
+ )
+ ],
+ )
+
+ self.assert_sql_count(testing.db, go, 1)
+
+
class DeprecatedQueryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
__dialect__ = "default"
@@ -310,10 +671,7 @@ class DeprecatedQueryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
q1 = s.query(User).options(joinedload("addresses"))
- with testing.expect_deprecated_20(
- "Using strings to indicate column or relationship "
- "paths in loader options"
- ):
+ with testing.expect_deprecated_20(opt_strings_dep):
self.assert_compile(
q1,
"SELECT users.id AS users_id, users.name AS users_name, "
@@ -2754,16 +3112,10 @@ class DeprecatedOptionAllTest(OptionsPathTest, _fixtures.FixtureTest):
sess = fixture_session()
- with testing.expect_deprecated(
- r"The \*addl_attrs on orm.defer is deprecated. "
- "Please use method chaining"
- ):
+ with testing.expect_deprecated(undefer_needs_chaining):
sess.query(User).options(defer("addresses", "email_address"))
- with testing.expect_deprecated(
- r"The \*addl_attrs on orm.undefer is deprecated. "
- "Please use method chaining"
- ):
+ with testing.expect_deprecated(undefer_needs_chaining):
sess.query(User).options(undefer("addresses", "email_address"))
@@ -3128,20 +3480,22 @@ class NonPrimaryRelationshipLoaderTest(_fixtures.FixtureTest):
closed_mapper = User.closed_orders.entity
open_mapper = User.open_orders.entity
- eq_(
- [Order(id=1), Order(id=5)],
- fixture_session()
- .query(closed_mapper)
- .with_parent(user, property="closed_orders")
- .all(),
- )
- eq_(
- [Order(id=3)],
- fixture_session()
- .query(open_mapper)
- .with_parent(user, property="open_orders")
- .all(),
- )
+ with testing.expect_deprecated_20(wparent_strings_dep):
+ eq_(
+ [Order(id=1), Order(id=5)],
+ fixture_session()
+ .query(closed_mapper)
+ .with_parent(user, property="closed_orders")
+ .all(),
+ )
+ with testing.expect_deprecated_20(wparent_strings_dep):
+ eq_(
+ [Order(id=3)],
+ fixture_session()
+ .query(open_mapper)
+ .with_parent(user, property="open_orders")
+ .all(),
+ )
class ViewonlyFlagWarningTest(fixtures.MappedTest):
@@ -4078,6 +4432,43 @@ class DeclarativeBind(fixtures.TestBase):
class JoinTest(QueryTest, AssertsCompiledSQL):
__dialect__ = "default"
+ @testing.combinations(
+ "string_relationship",
+ "string_relationship_only",
+ )
+ def test_filter_by_from_join(self, onclause_type):
+ User, Address = self.classes("User", "Address")
+ (address_table,) = self.tables("addresses")
+ (user_table,) = self.tables("users")
+
+ sess = fixture_session()
+ q = sess.query(User)
+
+ with assertions.expect_deprecated_20(join_strings_dep):
+ if onclause_type == "string_relationship":
+ q = q.join(Address, "addresses")
+ elif onclause_type == "string_relationship_only":
+ q = q.join("addresses")
+ else:
+ assert False
+
+ q2 = q.filter_by(email_address="foo")
+
+ self.assert_compile(
+ q2,
+ "SELECT users.id AS users_id, users.name AS users_name "
+ "FROM users JOIN addresses ON users.id = addresses.user_id "
+ "WHERE addresses.email_address = :email_address_1",
+ )
+
+ q2 = q.reset_joinpoint().filter_by(name="user")
+ self.assert_compile(
+ q2,
+ "SELECT users.id AS users_id, users.name AS users_name "
+ "FROM users JOIN addresses ON users.id = addresses.user_id "
+ "WHERE users.name = :name_1",
+ )
+
def test_implicit_joins_from_aliases(self):
Item, User, Order = (
self.classes.Item,
@@ -5266,6 +5657,75 @@ class InheritedJoinTest(
AssertsCompiledSQL,
):
run_setup_mappers = "once"
+ __dialect__ = "default"
+
+ def test_load_only_alias_subclass(self):
+ Manager = self.classes.Manager
+
+ s = fixture_session()
+ m1 = aliased(Manager, flat=True)
+ q = (
+ s.query(m1)
+ .order_by(m1.person_id)
+ .options(load_only("status", "manager_name"))
+ )
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self.assert_compile(
+ q,
+ "SELECT managers_1.person_id AS managers_1_person_id, "
+ "people_1.person_id AS people_1_person_id, "
+ "people_1.type AS people_1_type, "
+ "managers_1.status AS managers_1_status, "
+ "managers_1.manager_name AS managers_1_manager_name "
+ "FROM people AS people_1 JOIN managers AS "
+ "managers_1 ON people_1.person_id = managers_1.person_id "
+ "ORDER BY managers_1.person_id",
+ )
+
+ def test_load_only_alias_subclass_bound(self):
+ Manager = self.classes.Manager
+
+ s = fixture_session()
+ m1 = aliased(Manager, flat=True)
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ q = (
+ s.query(m1)
+ .order_by(m1.person_id)
+ .options(Load(m1).load_only("status", "manager_name"))
+ )
+ self.assert_compile(
+ q,
+ "SELECT managers_1.person_id AS managers_1_person_id, "
+ "people_1.person_id AS people_1_person_id, "
+ "people_1.type AS people_1_type, "
+ "managers_1.status AS managers_1_status, "
+ "managers_1.manager_name AS managers_1_manager_name "
+ "FROM people AS people_1 JOIN managers AS "
+ "managers_1 ON people_1.person_id = managers_1.person_id "
+ "ORDER BY managers_1.person_id",
+ )
+
+ def test_load_only_of_type_with_polymorphic(self):
+ Company, Person, Manager = self.classes("Company", "Person", "Manager")
+ s = fixture_session()
+
+ wp = with_polymorphic(Person, [Manager], flat=True)
+
+ # needs to be explicit, we don't currently dig onto all the
+ # sub-entities in the wp
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ r'Can\'t find property named "status" on '
+ r"with_polymorphic\(Person, \[Manager\]\) in this Query.",
+ s.query(Company)
+ .options(
+ joinedload(Company.employees.of_type(wp)).load_only(
+ "status"
+ )
+ )
+ ._compile_context,
+ )
def test_join_to_selectable(self):
people, Company, engineers, Engineer = (
@@ -5957,3 +6417,834 @@ class RequirementsTest(fixtures.MappedTest):
# TODO: is weakref support detectable without an instance?
# self.assertRaises(
# sa.exc.ArgumentError, mapper, NoWeakrefSupport, t2)
+
+
+class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
+ __dialect__ = "default"
+
+ def test_load_only_synonym(self):
+ orders, Order = self.tables.orders, self.classes.Order
+
+ self.mapper_registry.map_imperatively(
+ Order,
+ orders,
+ properties={"desc": synonym("description")},
+ )
+
+ opt = load_only("isopen", "desc")
+
+ sess = fixture_session()
+ q = sess.query(Order).options(opt)
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self.assert_compile(
+ q,
+ "SELECT orders.id AS orders_id, orders.description "
+ "AS orders_description, orders.isopen AS orders_isopen "
+ "FROM orders",
+ )
+
+ def test_deep_options(self):
+ users, items, order_items, Order, Item, User, orders = (
+ self.tables.users,
+ self.tables.items,
+ self.tables.order_items,
+ self.classes.Order,
+ self.classes.Item,
+ self.classes.User,
+ self.tables.orders,
+ )
+
+ self.mapper_registry.map_imperatively(
+ Item,
+ items,
+ properties=dict(description=deferred(items.c.description)),
+ )
+ self.mapper_registry.map_imperatively(
+ Order,
+ orders,
+ properties=dict(items=relationship(Item, secondary=order_items)),
+ )
+ self.mapper_registry.map_imperatively(
+ User,
+ users,
+ properties=dict(orders=relationship(Order, order_by=orders.c.id)),
+ )
+
+ sess = fixture_session()
+ q = sess.query(User).order_by(User.id)
+ result = q.all()
+ item = result[0].orders[1].items[1]
+
+ def go():
+ eq_(item.description, "item 4")
+
+ self.sql_count_(1, go)
+ eq_(item.description, "item 4")
+
+ sess.expunge_all()
+ with assertions.expect_deprecated(undefer_needs_chaining):
+ result = q.options(
+ undefer(User.orders, Order.items, Item.description)
+ ).all()
+ item = result[0].orders[1].items[1]
+
+ def go():
+ eq_(item.description, "item 4")
+
+ self.sql_count_(0, go)
+ eq_(item.description, "item 4")
+
+
+class OptionsTest(PathTest, OptionsQueryTest):
+ def _option_fixture(self, *arg):
+ return strategy_options._UnboundLoad._from_keys(
+ strategy_options._UnboundLoad.joinedload, arg, True, {}
+ )
+
+ def test_chained(self):
+ User = self.classes.User
+ Order = self.classes.Order
+ sess = fixture_session()
+ q = sess.query(User)
+ opt = self._option_fixture(User.orders).joinedload("items")
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_path_result(
+ opt, q, [(User, "orders"), (User, "orders", Order, "items")]
+ )
+
+ def test_chained_plus_dotted(self):
+ User = self.classes.User
+ Order = self.classes.Order
+ Item = self.classes.Item
+ sess = fixture_session()
+ q = sess.query(User)
+ opt = self._option_fixture("orders.items").joinedload("keywords")
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_path_result(
+ opt,
+ q,
+ [
+ (User, "orders"),
+ (User, "orders", Order, "items"),
+ (User, "orders", Order, "items", Item, "keywords"),
+ ],
+ )
+
+ def test_with_current_matching_string(self):
+ Item, User, Order = (
+ self.classes.Item,
+ self.classes.User,
+ self.classes.Order,
+ )
+
+ sess = fixture_session()
+ q = sess.query(Item)._with_current_path(
+ self._make_path_registry([User, "orders", Order, "items"])
+ )
+
+ opt = self._option_fixture("orders.items.keywords")
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_path_result(opt, q, [(Item, "keywords")])
+
+ def test_with_current_nonmatching_string(self):
+ Item, User, Order = (
+ self.classes.Item,
+ self.classes.User,
+ self.classes.Order,
+ )
+
+ sess = fixture_session()
+ q = sess.query(Item)._with_current_path(
+ self._make_path_registry([User, "orders", Order, "items"])
+ )
+
+ opt = self._option_fixture("keywords")
+ self._assert_path_result(opt, q, [])
+
+ opt = self._option_fixture("items.keywords")
+ self._assert_path_result(opt, q, [])
+
+ def test_path_multilevel_string(self):
+ Item, User, Order = (
+ self.classes.Item,
+ self.classes.User,
+ self.classes.Order,
+ )
+
+ sess = fixture_session()
+ q = sess.query(User)
+
+ opt = self._option_fixture("orders.items.keywords")
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_path_result(
+ opt,
+ q,
+ [
+ (User, "orders"),
+ (User, "orders", Order, "items"),
+ (User, "orders", Order, "items", Item, "keywords"),
+ ],
+ )
+
+ def test_chained_plus_multi(self):
+ User = self.classes.User
+ Order = self.classes.Order
+ Item = self.classes.Item
+ sess = fixture_session()
+ q = sess.query(User)
+ opt = self._option_fixture(User.orders, Order.items).joinedload(
+ "keywords"
+ )
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_path_result(
+ opt,
+ q,
+ [
+ (User, "orders"),
+ (User, "orders", Order, "items"),
+ (User, "orders", Order, "items", Item, "keywords"),
+ ],
+ )
+
+ def test_multi_entity_opt_on_string(self):
+ Item = self.classes.Item
+ Order = self.classes.Order
+ opt = self._option_fixture("items")
+ sess = fixture_session()
+ q = sess.query(Item, Order)
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_path_result(opt, q, [])
+
+ def test_get_path_one_level_string(self):
+ User = self.classes.User
+
+ sess = fixture_session()
+ q = sess.query(User)
+
+ opt = self._option_fixture("addresses")
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_path_result(opt, q, [(User, "addresses")])
+
+ def test_get_path_one_level_with_unrelated(self):
+ Order = self.classes.Order
+
+ sess = fixture_session()
+ q = sess.query(Order)
+ opt = self._option_fixture("addresses")
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_path_result(opt, q, [])
+
+
+class SubOptionsTest(PathTest, OptionsQueryTest):
+ run_create_tables = False
+ run_inserts = None
+ run_deletes = None
+
+ def _assert_opts(self, q, sub_opt, non_sub_opts):
+ attr_a = {}
+
+ for val in sub_opt._to_bind:
+ val._bind_loader(
+ [
+ ent.entity_zero
+ for ent in q._compile_state()._lead_mapper_entities
+ ],
+ q._compile_options._current_path,
+ attr_a,
+ False,
+ )
+
+ attr_b = {}
+
+ for opt in non_sub_opts:
+ for val in opt._to_bind:
+ val._bind_loader(
+ [
+ ent.entity_zero
+ for ent in q._compile_state()._lead_mapper_entities
+ ],
+ q._compile_options._current_path,
+ attr_b,
+ False,
+ )
+
+ for k, l in attr_b.items():
+ if not l.strategy:
+ del attr_b[k]
+
+ def strat_as_tuple(strat):
+ return (
+ strat.strategy,
+ strat.local_opts,
+ strat.propagate_to_loaders,
+ strat._of_type,
+ strat.is_class_strategy,
+ strat.is_opts_only,
+ )
+
+ eq_(
+ {path: strat_as_tuple(load) for path, load in attr_a.items()},
+ {path: strat_as_tuple(load) for path, load in attr_b.items()},
+ )
+
+ def test_invalid_two(self):
+ User, Address, Order, Item, SubItem = self.classes(
+ "User", "Address", "Order", "Item", "SubItem"
+ )
+
+ # these options are "invalid", in that User.orders -> Item.keywords
+ # is not a path. However, the "normal" option is not generating
+ # an error for now, which is bad, but we're testing here only that
+ # it works the same way, so there you go. If and when we make this
+ # case raise, then both cases should raise in the same way.
+ sub_opt = joinedload("orders").options(
+ joinedload("keywords"), joinedload("items")
+ )
+ non_sub_opts = [
+ joinedload(User.orders).joinedload(Item.keywords),
+ defaultload(User.orders).joinedload(Order.items),
+ ]
+ sess = fixture_session()
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
+
+ def test_four_strings(self):
+ User, Address, Order, Item, SubItem, Keyword = self.classes(
+ "User", "Address", "Order", "Item", "SubItem", "Keyword"
+ )
+ sub_opt = joinedload("orders").options(
+ defer("description"),
+ joinedload("items").options(
+ joinedload("keywords").options(defer("name")),
+ defer("description"),
+ ),
+ )
+ non_sub_opts = [
+ joinedload(User.orders),
+ defaultload(User.orders).defer(Order.description),
+ defaultload(User.orders).joinedload(Order.items),
+ defaultload(User.orders)
+ .defaultload(Order.items)
+ .joinedload(Item.keywords),
+ defaultload(User.orders)
+ .defaultload(Order.items)
+ .defer(Item.description),
+ defaultload(User.orders)
+ .defaultload(Order.items)
+ .defaultload(Item.keywords)
+ .defer(Keyword.name),
+ ]
+ sess = fixture_session()
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
+
+ def test_five_strings(self):
+ User, Address, Order, Item, SubItem, Keyword = self.classes(
+ "User", "Address", "Order", "Item", "SubItem", "Keyword"
+ )
+ sub_opt = joinedload("orders").options(load_only("description"))
+ non_sub_opts = [
+ joinedload(User.orders),
+ defaultload(User.orders).load_only(Order.description),
+ ]
+ sess = fixture_session()
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
+
+
+class OptionsNoPropTest(_fixtures.FixtureTest):
+ """test the error messages emitted when using property
+ options in conjunction with column-only entities, or
+ for not existing options
+
+ """
+
+ run_create_tables = False
+ run_inserts = None
+ run_deletes = None
+
+ def test_option_with_column_basestring(self):
+ Item = self.classes.Item
+
+ message = (
+ "Query has only expression-based entities - can't "
+ 'find property named "keywords".'
+ )
+ self._assert_eager_with_just_column_exception(
+ Item.id, "keywords", message
+ )
+
+ def test_option_against_nonexistent_basestring(self):
+ Item = self.classes.Item
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_eager_with_entity_exception(
+ [Item],
+ (joinedload("foo"),),
+ 'Can\'t find property named "foo" on mapped class '
+ "Item->items in this Query.",
+ )
+
+ def test_option_against_nonexistent_twolevel_basestring(self):
+ Item = self.classes.Item
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_eager_with_entity_exception(
+ [Item],
+ (joinedload("keywords.foo"),),
+ 'Can\'t find property named "foo" on mapped class '
+ "Keyword->keywords in this Query.",
+ )
+
+ def test_option_against_nonexistent_twolevel_chained(self):
+ Item = self.classes.Item
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_eager_with_entity_exception(
+ [Item],
+ (joinedload("keywords").joinedload("foo"),),
+ 'Can\'t find property named "foo" on mapped class '
+ "Keyword->keywords in this Query.",
+ )
+
+ @testing.fails_if(
+ lambda: True,
+ "PropertyOption doesn't yet check for relation/column on end result",
+ )
+ def test_option_against_non_relation_basestring(self):
+ Item = self.classes.Item
+ Keyword = self.classes.Keyword
+ self._assert_eager_with_entity_exception(
+ [Keyword, Item],
+ (joinedload("keywords"),),
+ r"Attribute 'keywords' of entity 'Mapper\|Keyword\|keywords' "
+ "does not refer to a mapped entity",
+ )
+
+ @testing.fails_if(
+ lambda: True,
+ "PropertyOption doesn't yet check for relation/column on end result",
+ )
+ def test_option_against_multi_non_relation_basestring(self):
+ Item = self.classes.Item
+ Keyword = self.classes.Keyword
+ self._assert_eager_with_entity_exception(
+ [Keyword, Item],
+ (joinedload("keywords"),),
+ r"Attribute 'keywords' of entity 'Mapper\|Keyword\|keywords' "
+ "does not refer to a mapped entity",
+ )
+
+ def test_option_against_wrong_entity_type_basestring(self):
+ Item = self.classes.Item
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_loader_strategy_exception(
+ [Item],
+ (joinedload("id").joinedload("keywords"),),
+ 'Can\'t apply "joined loader" strategy to property "Item.id", '
+ 'which is a "column property"; this loader strategy is '
+ 'intended to be used with a "relationship property".',
+ )
+
+ def test_col_option_against_relationship_basestring(self):
+ Item = self.classes.Item
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_loader_strategy_exception(
+ [Item],
+ (load_only("keywords"),),
+ 'Can\'t apply "column loader" strategy to property '
+ '"Item.keywords", which is a "relationship property"; this '
+ "loader strategy is intended to be used with a "
+ '"column property".',
+ )
+
+ def test_option_against_multi_non_relation_twolevel_basestring(self):
+ Item = self.classes.Item
+ Keyword = self.classes.Keyword
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_loader_strategy_exception(
+ [Keyword, Item],
+ (joinedload("id").joinedload("keywords"),),
+ 'Can\'t apply "joined loader" strategy to property '
+ '"Keyword.id", '
+ 'which is a "column property"; this loader strategy is '
+ "intended "
+ 'to be used with a "relationship property".',
+ )
+
+ def test_option_against_multi_nonexistent_basestring(self):
+ Item = self.classes.Item
+ Keyword = self.classes.Keyword
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_eager_with_entity_exception(
+ [Keyword, Item],
+ (joinedload("description"),),
+ 'Can\'t find property named "description" on mapped class '
+ "Keyword->keywords in this Query.",
+ )
+
+ def test_option_against_multi_no_entities_basestring(self):
+ Item = self.classes.Item
+ Keyword = self.classes.Keyword
+ self._assert_eager_with_entity_exception(
+ [Keyword.id, Item.id],
+ (joinedload("keywords"),),
+ r"Query has only expression-based entities - can't find property "
+ 'named "keywords".',
+ )
+
+ def test_option_with_mapper_then_column_basestring(self):
+ Item = self.classes.Item
+
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_option([Item, Item.id], "keywords")
+
+ def test_option_with_mapper_basestring(self):
+ Item = self.classes.Item
+
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_option([Item], "keywords")
+
+ def test_option_with_column_then_mapper_basestring(self):
+ Item = self.classes.Item
+
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self._assert_option([Item.id, Item], "keywords")
+
+ @classmethod
+ def setup_mappers(cls):
+ users, User, addresses, Address, orders, Order = (
+ cls.tables.users,
+ cls.classes.User,
+ cls.tables.addresses,
+ cls.classes.Address,
+ cls.tables.orders,
+ cls.classes.Order,
+ )
+ cls.mapper_registry.map_imperatively(
+ User,
+ users,
+ properties={
+ "addresses": relationship(Address),
+ "orders": relationship(Order),
+ },
+ )
+ cls.mapper_registry.map_imperatively(Address, addresses)
+ cls.mapper_registry.map_imperatively(Order, orders)
+ keywords, items, item_keywords, Keyword, Item = (
+ cls.tables.keywords,
+ cls.tables.items,
+ cls.tables.item_keywords,
+ cls.classes.Keyword,
+ cls.classes.Item,
+ )
+ cls.mapper_registry.map_imperatively(
+ Keyword,
+ keywords,
+ properties={
+ "keywords": column_property(keywords.c.name + "some keyword")
+ },
+ )
+ cls.mapper_registry.map_imperatively(
+ Item,
+ items,
+ properties=dict(
+ keywords=relationship(Keyword, secondary=item_keywords)
+ ),
+ )
+
+ class OrderWProp(cls.classes.Order):
+ @property
+ def some_attr(self):
+ return "hi"
+
+ cls.mapper_registry.map_imperatively(
+ OrderWProp, None, inherits=cls.classes.Order
+ )
+
+ def _assert_option(self, entity_list, option):
+ Item = self.classes.Item
+
+ context = (
+ fixture_session()
+ .query(*entity_list)
+ .options(joinedload(option))
+ ._compile_state()
+ )
+ key = ("loader", (inspect(Item), inspect(Item).attrs.keywords))
+ assert key in context.attributes
+
+ def _assert_loader_strategy_exception(self, entity_list, options, message):
+ assert_raises_message(
+ orm_exc.LoaderStrategyException,
+ message,
+ fixture_session()
+ .query(*entity_list)
+ .options(*options)
+ ._compile_state,
+ )
+
+ def _assert_eager_with_entity_exception(
+ self, entity_list, options, message
+ ):
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ message,
+ fixture_session()
+ .query(*entity_list)
+ .options(*options)
+ ._compile_state,
+ )
+
+ def _assert_eager_with_just_column_exception(
+ self, column, eager_option, message
+ ):
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ message,
+ fixture_session()
+ .query(column)
+ .options(joinedload(eager_option))
+ ._compile_state,
+ )
+
+
+class OptionsNoPropTestInh(_Polymorphic):
+ def test_missing_str_attr_of_type_subclass(self):
+ s = fixture_session()
+
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ r'Can\'t find property named "manager_name" on '
+ r"mapped class Engineer->engineers in this Query.$",
+ s.query(Company)
+ .options(
+ joinedload(Company.employees.of_type(Engineer)).load_only(
+ "manager_name"
+ )
+ )
+ ._compile_state,
+ )
+
+
+class CacheKeyTest(CacheKeyFixture, _fixtures.FixtureTest):
+ """In these tests we've moved / adapted all the tests from
+ test_cache_key that make use of string options or string join(). Because
+ we are ensuring cache keys are distinct we still keep a lot of the
+ non-deprecated cases in the lists that we are testing.
+
+ """
+
+ run_setup_mappers = "once"
+ run_inserts = None
+ run_deletes = None
+
+ @classmethod
+ def setup_mappers(cls):
+ cls._setup_stock_mapping()
+
+ def _stmt_20(self, *elements):
+ return tuple(
+ elem._statement_20() if isinstance(elem, sa.orm.Query) else elem
+ for elem in elements
+ )
+
+ def _deprecated_opt(self, fn):
+ with assertions.expect_deprecated_20(
+ opt_strings_dep, raise_on_any_unexpected=True
+ ):
+ return fn()
+
+ def _deprecated_join(self, fn):
+ with assertions.expect_deprecated_20(
+ join_strings_dep, raise_on_any_unexpected=True
+ ):
+ return fn()
+
+ def _deprecated_join_w_aliased(self, fn):
+ with assertions.expect_deprecated_20(
+ join_strings_dep, join_aliased_dep, raise_on_any_unexpected=True
+ ):
+ return fn()
+
+ def test_bound_options(self):
+ User, Address, Keyword, Order, Item = self.classes(
+ "User", "Address", "Keyword", "Order", "Item"
+ )
+
+ self._run_cache_key_fixture(
+ lambda: (
+ Load(User).joinedload(User.addresses),
+ Load(User).joinedload(
+ User.addresses.of_type(aliased(Address))
+ ),
+ Load(User).joinedload(User.orders),
+ self._deprecated_opt(
+ lambda: Load(User).subqueryload("addresses")
+ ),
+ self._deprecated_opt(lambda: Load(Address).defer("id")),
+ Load(Address).defer("*"),
+ self._deprecated_opt(
+ lambda: Load(aliased(Address)).defer("id")
+ ),
+ Load(User).joinedload(User.addresses).defer(Address.id),
+ Load(User).joinedload(User.orders).joinedload(Order.items),
+ Load(User).joinedload(User.orders).subqueryload(Order.items),
+ Load(User).subqueryload(User.orders).subqueryload(Order.items),
+ Load(Address).raiseload("*"),
+ self._deprecated_opt(lambda: Load(Address).raiseload("user")),
+ ),
+ compare_values=True,
+ )
+
+ def test_bound_options_equiv_on_strname(self):
+ """Bound loader options resolve on string name so test that the cache
+ key for the string version matches the resolved version.
+
+ """
+ User, Address, Keyword, Order, Item = self.classes(
+ "User", "Address", "Keyword", "Order", "Item"
+ )
+
+ for left, right in [
+ (
+ Load(User).defer(User.id),
+ self._deprecated_opt(lambda: Load(User).defer("id")),
+ ),
+ (
+ Load(User).joinedload(User.addresses),
+ self._deprecated_opt(
+ lambda: Load(User).joinedload("addresses")
+ ),
+ ),
+ (
+ Load(User).joinedload(User.orders).joinedload(Order.items),
+ self._deprecated_opt(
+ lambda: Load(User).joinedload("orders").joinedload("items")
+ ),
+ ),
+ ]:
+ eq_(left._generate_cache_key(), right._generate_cache_key())
+
+ def test_orm_query_w_orm_joins(self):
+
+ User, Address, Keyword, Order, Item = self.classes(
+ "User", "Address", "Keyword", "Order", "Item"
+ )
+
+ a1 = aliased(Address)
+
+ self._run_cache_key_fixture(
+ lambda: self._stmt_20(
+ fixture_session().query(User).join(User.addresses),
+ fixture_session().query(User).join(User.orders),
+ fixture_session()
+ .query(User)
+ .join(User.addresses)
+ .join(User.orders),
+ self._deprecated_join_w_aliased(
+ lambda: fixture_session()
+ .query(User)
+ .join("addresses")
+ .join("dingalings", from_joinpoint=True)
+ ),
+ self._deprecated_join(
+ lambda: fixture_session().query(User).join("addresses")
+ ),
+ self._deprecated_join(
+ lambda: fixture_session().query(User).join("orders")
+ ),
+ self._deprecated_join(
+ lambda: fixture_session()
+ .query(User)
+ .join("addresses")
+ .join("orders")
+ ),
+ fixture_session().query(User).join(Address, User.addresses),
+ self._deprecated_join(
+ lambda: fixture_session().query(User).join(a1, "addresses")
+ ),
+ self._deprecated_join_w_aliased(
+ lambda: fixture_session()
+ .query(User)
+ .join(a1, "addresses", aliased=True)
+ ),
+ fixture_session().query(User).join(User.addresses.of_type(a1)),
+ ),
+ compare_values=True,
+ )
+
+ def test_unbound_options(self):
+ User, Address, Keyword, Order, Item = self.classes(
+ "User", "Address", "Keyword", "Order", "Item"
+ )
+
+ # unbound options dont emit a deprecation warning during cache
+ # key generation
+ self._run_cache_key_fixture(
+ lambda: (
+ joinedload(User.addresses),
+ joinedload(User.addresses.of_type(aliased(Address))),
+ joinedload("addresses"),
+ joinedload(User.orders),
+ joinedload(User.orders.and_(Order.id != 5)),
+ joinedload(User.orders).selectinload("items"),
+ joinedload(User.orders).selectinload(Order.items),
+ defer(User.id),
+ defer("id"),
+ defer("*"),
+ defer(Address.id),
+ joinedload(User.addresses).defer(Address.id),
+ joinedload(User.addresses).defer("id"),
+ subqueryload(User.orders)
+ .subqueryload(Order.items)
+ .defer(Item.description),
+ defaultload(User.orders).defaultload(Order.items),
+ defaultload(User.orders),
+ ),
+ compare_values=True,
+ )
+
+ def test_unbound_sub_options(self):
+ """test #6869"""
+
+ User, Address, Keyword, Order, Item = self.classes(
+ "User", "Address", "Keyword", "Order", "Item"
+ )
+
+ self._run_cache_key_fixture(
+ lambda: (
+ joinedload(User.addresses).options(
+ joinedload(Address.dingaling)
+ ),
+ joinedload(User.addresses).options(
+ joinedload(Address.dingaling).options(load_only("name"))
+ ),
+ joinedload(User.orders).options(
+ joinedload(Order.items).options(joinedload(Item.keywords))
+ ),
+ ),
+ compare_values=True,
+ )
+
+
+class AliasedClassRelationshipTest(
+ PartitionByFixture, testing.AssertsCompiledSQL
+):
+ __requires__ = ("window_functions",)
+ __dialect__ = "default"
+
+ def test_selectinload_w_joinedload_after(self):
+ """test has been enhanced to also test #7224"""
+
+ A, B, C = self.classes("A", "B", "C")
+
+ s = Session(testing.db)
+
+ opt = selectinload(A.partitioned_bs).joinedload("cs")
+
+ def go():
+ for a1 in s.query(A).options(opt):
+ for b in a1.partitioned_bs:
+ eq_(len(b.cs), 2)
+
+ with assertions.expect_deprecated_20(opt_strings_dep):
+ self.assert_sql_count(testing.db, go, 2)
diff --git a/test/orm/test_eager_relations.py b/test/orm/test_eager_relations.py
index cb578ee2d..c235edadf 100644
--- a/test/orm/test_eager_relations.py
+++ b/test/orm/test_eager_relations.py
@@ -754,7 +754,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
def go():
eq_(
self.static.item_keyword_result[0:2],
- q.join("keywords").filter(Keyword.name == "red").all(),
+ q.join(Item.keywords).filter(Keyword.name == "red").all(),
)
self.assert_sql_count(testing.db, go, 1)
@@ -763,7 +763,9 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
ka = aliased(Keyword)
eq_(
self.static.item_keyword_result[0:2],
- (q.join(ka, "keywords").filter(ka.name == "red")).all(),
+ (
+ q.join(Item.keywords.of_type(ka)).filter(ka.name == "red")
+ ).all(),
)
self.assert_sql_count(testing.db, go, 1)
@@ -1401,7 +1403,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
if not testing.against("mssql"):
result = (
- q.join("orders")
+ q.join(User.orders)
.order_by(Order.user_id.desc())
.limit(2)
.offset(1)
@@ -1423,7 +1425,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
)
result = (
- q.join("addresses")
+ q.join(User.addresses)
.order_by(Address.email_address.desc())
.limit(1)
.offset(0)
@@ -4040,7 +4042,7 @@ class AddEntityTest(_fixtures.FixtureTest):
def go():
ret = (
sess.query(User, oalias)
- .join(oalias, "orders")
+ .join(User.orders.of_type(oalias))
.order_by(User.id, oalias.id)
.all()
)
@@ -4099,7 +4101,7 @@ class AddEntityTest(_fixtures.FixtureTest):
ret = (
sess.query(User, oalias)
.options(joinedload(User.addresses))
- .join(oalias, "orders")
+ .join(User.orders.of_type(oalias))
.order_by(User.id, oalias.id)
.all()
)
@@ -4113,7 +4115,7 @@ class AddEntityTest(_fixtures.FixtureTest):
ret = (
sess.query(User, oalias)
.options(joinedload(User.addresses), joinedload(oalias.items))
- .join(oalias, "orders")
+ .join(User.orders.of_type(oalias))
.order_by(User.id, oalias.id)
.all()
)
@@ -5972,7 +5974,9 @@ class EntityViaMultiplePathTestTwo(fixtures.DeclarativeMappedTest):
s.query(LDA)
.join(LDA.ld)
.options(contains_eager(LDA.ld))
- .join("a", (l_ac, "ld"), (u_ac, "user"))
+ .join(LDA.a)
+ .join(A.ld.of_type(l_ac))
+ .join(l_ac.user.of_type(u_ac))
.options(
contains_eager(LDA.a)
.contains_eager(A.ld, alias=l_ac)
diff --git a/test/orm/test_expire.py b/test/orm/test_expire.py
index 92a7ea42d..d9204db96 100644
--- a/test/orm/test_expire.py
+++ b/test/orm/test_expire.py
@@ -1157,7 +1157,7 @@ class ExpireTest(_fixtures.FixtureTest):
assert "addresses" not in u.__dict__
(
sess.query(User)
- .options(sa.orm.joinedload("addresses"))
+ .options(sa.orm.joinedload(User.addresses))
.filter_by(id=8)
.all()
)
@@ -1206,7 +1206,7 @@ class ExpireTest(_fixtures.FixtureTest):
sess.expunge_all()
# same tests, using deferred at the options level
- o = sess.query(Order).options(sa.orm.defer("description")).get(3)
+ o = sess.query(Order).options(sa.orm.defer(Order.description)).get(3)
assert "description" not in o.__dict__
@@ -1983,7 +1983,7 @@ class RefreshTest(_fixtures.FixtureTest):
)
},
)
- q = s.query(User).options(sa.orm.lazyload("addresses"))
+ q = s.query(User).options(sa.orm.lazyload(User.addresses))
u = q.filter(users.c.id == 8).first()
def go():
@@ -2049,7 +2049,9 @@ class RefreshTest(_fixtures.FixtureTest):
q = (
s.query(User)
.filter_by(name="fred")
- .options(sa.orm.lazyload("addresses").joinedload("dingalings"))
+ .options(
+ sa.orm.lazyload(User.addresses).joinedload(Address.dingalings)
+ )
)
u1 = q.one()
diff --git a/test/orm/test_froms.py b/test/orm/test_froms.py
index d6579cebd..3351967fc 100644
--- a/test/orm/test_froms.py
+++ b/test/orm/test_froms.py
@@ -1098,7 +1098,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
def go():
result = (
- q.options(contains_eager("addresses"))
+ q.options(contains_eager(User.addresses))
.from_statement(query)
.all()
)
@@ -1129,7 +1129,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
ulist = query.alias("ulist")
ulist_alias = aliased(User, alias=ulist)
result = (
- q.options(contains_eager("addresses", alias=ulist))
+ q.options(contains_eager(User.addresses, alias=ulist))
.select_entity_from(ulist_alias)
.all()
)
@@ -1160,7 +1160,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
result = (
sess.query(User)
.select_entity_from(query.subquery())
- .options(contains_eager("addresses"))
+ .options(contains_eager(User.addresses))
.all()
)
assert self.static.user_address_result == result
@@ -1194,7 +1194,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
result = (
sess.query(User)
.select_entity_from(query.subquery())
- .options(contains_eager("addresses", alias=adalias))
+ .options(contains_eager(User.addresses, alias=adalias))
.all()
)
assert self.static.user_address_result == result
@@ -1273,7 +1273,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
def go():
result = (
- q.options(contains_eager("addresses"))
+ q.options(contains_eager(User.addresses))
.from_statement(selectquery)
.all()
)
@@ -1302,7 +1302,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
def go():
result = (
sess.execute(
- q.options(contains_eager("addresses")).from_statement(
+ q.options(contains_eager(User.addresses)).from_statement(
selectquery
)
)
@@ -1325,7 +1325,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
def go():
result = (
- q.options(contains_eager("addresses", alias=adalias))
+ q.options(contains_eager(User.addresses.of_type(adalias)))
.outerjoin(adalias, User.addresses)
.order_by(User.id, adalias.id)
)
@@ -1341,6 +1341,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
self.tables.order_items,
self.classes.User,
)
+ Order = self.classes.Order
sess = fixture_session()
q = sess.query(User)
@@ -1357,16 +1358,12 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
# test using Alias with more than one level deep
- # new way:
- # from sqlalchemy.orm.strategy_options import Load
- # opt = Load(User).contains_eager('orders', alias=oalias).
- # contains_eager('items', alias=ialias)
-
def go():
result = list(
q.options(
- contains_eager("orders", alias=oalias),
- contains_eager("orders.items", alias=ialias),
+ contains_eager(User.orders, alias=oalias).contains_eager(
+ Order.items, alias=ialias
+ ),
).from_statement(query)
)
assert self.static.user_order_result == result
@@ -1869,7 +1866,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
adalias = aliased(Address)
eq_(
sess.query(User, func.count(adalias.email_address))
- .outerjoin(adalias, "addresses")
+ .outerjoin(User.addresses.of_type(adalias))
.group_by(User)
.order_by(User.id)
.all(),
@@ -2110,7 +2107,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
results = (
sess.query(User)
.limit(1)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.add_columns(User.name)
.all()
)
@@ -2321,21 +2318,21 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
q = (
sess.query(User)
.add_entity(address_entity)
- .outerjoin(address_entity, "addresses")
+ .outerjoin(address_entity, User.addresses)
.order_by(User.id, address_entity.id)
)
eq_(q.all(), expected)
sess.expunge_all()
q = sess.query(User).add_entity(address_entity)
- q = q.join(address_entity, "addresses")
+ q = q.join(address_entity, User.addresses)
q = q.filter_by(email_address="ed@bettyboop.com")
eq_(q.all(), [(user8, address3)])
sess.expunge_all()
q = (
sess.query(User, address_entity)
- .join(address_entity, "addresses")
+ .join(address_entity, User.addresses)
.filter_by(email_address="ed@bettyboop.com")
)
eq_(q.all(), [(user8, address3)])
@@ -2343,8 +2340,8 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
q = (
sess.query(User, address_entity)
- .join(address_entity, "addresses")
- .options(joinedload("addresses"))
+ .join(address_entity, User.addresses)
+ .options(joinedload(User.addresses))
.filter_by(email_address="ed@bettyboop.com")
)
eq_(list(util.OrderedSet(q.all())), [(user8, address3)])
@@ -2458,7 +2455,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
q = (
q.group_by(users)
.order_by(User.id)
- .outerjoin("addresses")
+ .outerjoin(User.addresses)
.add_columns(func.count(Address.id).label("count"))
)
eq_(q.all(), expected)
@@ -2469,7 +2466,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
q = (
q.group_by(users)
.order_by(User.id)
- .outerjoin(adalias, "addresses")
+ .outerjoin(User.addresses.of_type(adalias))
.add_columns(func.count(adalias.id).label("count"))
)
eq_(q.all(), expected)
@@ -2576,7 +2573,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
.add_columns(
func.count(addresses.c.id), ("Name:" + users.c.name)
)
- .outerjoin("addresses")
+ .outerjoin(User.addresses)
.group_by(users)
.order_by(users.c.id)
)
@@ -2604,21 +2601,21 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
for crit, j, exp in [
(
User.id + Address.id,
- User.addresses,
+ (User.addresses,),
"SELECT users.id + addresses.id AS anon_1 "
"FROM users JOIN addresses ON users.id = "
"addresses.user_id",
),
(
User.id + Address.id,
- Address.user,
+ (Address.user,),
"SELECT users.id + addresses.id AS anon_1 "
"FROM addresses JOIN users ON users.id = "
"addresses.user_id",
),
(
Address.id + User.id,
- User.addresses,
+ (User.addresses,),
"SELECT addresses.id + users.id AS anon_1 "
"FROM users JOIN addresses ON users.id = "
"addresses.user_id",
@@ -2634,13 +2631,13 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
q = s.query(crit)
mzero = q._compile_state()._entity_zero()
is_(mzero, q._compile_state()._entities[0].entity_zero)
- q = q.join(j)
+ q = q.join(*j)
self.assert_compile(q, exp)
for crit, j, exp in [
(
ua.id + Address.id,
- ua.addresses,
+ (ua.addresses,),
"SELECT users_1.id + addresses.id AS anon_1 "
"FROM users AS users_1 JOIN addresses "
"ON users_1.id = addresses.user_id",
@@ -2664,7 +2661,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
q = s.query(crit)
mzero = q._compile_state()._entity_zero()
is_(mzero, q._compile_state()._entities[0].entity_zero)
- q = q.join(j)
+ q = q.join(*j)
self.assert_compile(q, exp)
def test_aliased_adapt_on_names(self):
@@ -2764,7 +2761,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
eq_(
sess.query(User)
.select_entity_from(sel)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.first(),
User(name="jack", addresses=[Address(id=1)]),
)
@@ -2980,7 +2977,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
sess = fixture_session()
self.assert_compile(
- sess.query(User).select_from(Address).join("user"),
+ sess.query(User).select_from(Address).join(Address.user),
"SELECT users.id AS users_id, users.name AS users_name "
"FROM addresses JOIN users ON users.id = addresses.user_id",
)
@@ -3050,7 +3047,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
eq_(
sess.query(User)
.select_entity_from(sel.subquery())
- .join("addresses")
+ .join(User.addresses)
.add_entity(Address)
.order_by(User.id)
.order_by(Address.id)
@@ -3079,7 +3076,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
eq_(
sess.query(User)
.select_entity_from(sel.subquery())
- .join(adalias, "addresses")
+ .join(adalias, User.addresses)
.add_entity(adalias)
.order_by(User.id)
.order_by(adalias.id)
@@ -3161,7 +3158,9 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
eq_(
sess.query(User)
.select_entity_from(sel.subquery())
- .join(User.orders, Order.items, Item.keywords)
+ .join(User.orders)
+ .join(Order.items)
+ .join(Item.keywords)
.filter(Keyword.name.in_(["red", "big", "round"]))
.all(),
[User(name="jack", id=7)],
@@ -3226,11 +3225,13 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
sess.query(User)
.select_entity_from(sel.subquery())
.options(
- joinedload("orders")
- .joinedload("items")
- .joinedload("keywords")
+ joinedload(User.orders)
+ .joinedload(Order.items)
+ .joinedload(Item.keywords)
)
- .join(User.orders, Order.items, Item.keywords)
+ .join(User.orders)
+ .join(Order.items)
+ .join(Item.keywords)
.filter(Keyword.name.in_(["red", "big", "round"]))
.all(),
[
@@ -3337,7 +3338,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
def go():
eq_(
sess.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.select_entity_from(sel.subquery())
.order_by(User.id)
.all(),
@@ -3360,7 +3361,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
def go():
eq_(
sess.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.select_entity_from(sel.subquery())
.filter(User.id == 8)
.order_by(User.id)
@@ -3383,7 +3384,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
def go():
eq_(
sess.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.select_entity_from(sel.subquery())
.order_by(User.id)[1],
User(
@@ -3398,79 +3399,6 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
class CustomJoinTest(QueryTest):
run_setup_mappers = None
- def test_double_same_mappers_flag_alias(self):
- """test aliasing of joins with a custom join condition"""
-
- (
- addresses,
- items,
- order_items,
- orders,
- Item,
- User,
- Address,
- Order,
- users,
- ) = (
- self.tables.addresses,
- self.tables.items,
- self.tables.order_items,
- self.tables.orders,
- self.classes.Item,
- self.classes.User,
- self.classes.Address,
- self.classes.Order,
- self.tables.users,
- )
-
- self.mapper_registry.map_imperatively(Address, addresses)
- self.mapper_registry.map_imperatively(
- Order,
- orders,
- properties={
- "items": relationship(
- Item,
- secondary=order_items,
- lazy="select",
- order_by=items.c.id,
- )
- },
- )
- self.mapper_registry.map_imperatively(Item, items)
- self.mapper_registry.map_imperatively(
- User,
- users,
- properties=dict(
- addresses=relationship(Address, lazy="select"),
- open_orders=relationship(
- Order,
- primaryjoin=and_(
- orders.c.isopen == 1, users.c.id == orders.c.user_id
- ),
- lazy="select",
- viewonly=True,
- ),
- closed_orders=relationship(
- Order,
- primaryjoin=and_(
- orders.c.isopen == 0, users.c.id == orders.c.user_id
- ),
- lazy="select",
- viewonly=True,
- ),
- ),
- )
- q = fixture_session().query(User)
-
- eq_(
- q.join("open_orders", "items", aliased=True)
- .filter(Item.id == 4)
- .join("closed_orders", "items", aliased=True)
- .filter(Item.id == 3)
- .all(),
- [User(id=7)],
- )
-
def test_double_same_mappers_explicit_alias(self):
"""test aliasing of joins with a custom join condition"""
@@ -3614,7 +3542,7 @@ class ExternalColumnsTest(QueryTest):
sess = fixture_session()
- sess.query(Address).options(joinedload("user")).all()
+ sess.query(Address).options(joinedload(Address.user)).all()
eq_(
sess.query(User).all(),
@@ -3647,7 +3575,7 @@ class ExternalColumnsTest(QueryTest):
def go():
eq_(
sess.query(Address)
- .options(joinedload("user"))
+ .options(joinedload(Address.user))
.order_by(Address.id)
.all(),
address_result,
@@ -3657,15 +3585,15 @@ class ExternalColumnsTest(QueryTest):
ualias = aliased(User)
eq_(
- sess.query(Address, ualias).join(ualias, "user").all(),
+ sess.query(Address, ualias).join(ualias, Address.user).all(),
[(address, address.user) for address in address_result],
)
ualias2 = aliased(User)
eq_(
sess.query(Address, ualias.count)
- .join(ualias, "user")
- .join(ualias2, "user")
+ .join(ualias, Address.user)
+ .join(ualias2, Address.user)
.order_by(Address.id)
.all(),
[
@@ -3679,8 +3607,8 @@ class ExternalColumnsTest(QueryTest):
eq_(
sess.query(Address, ualias.concat, ualias.count)
- .join(ualias, "user")
- .join(ualias2, "user")
+ .join(Address.user.of_type(ualias))
+ .join(Address.user.of_type(ualias2))
.order_by(Address.id)
.all(),
[
@@ -3711,7 +3639,7 @@ class ExternalColumnsTest(QueryTest):
eq_(
list(
sess.query(Address)
- .join("user")
+ .join(Address.user)
.with_entities(Address.id, User.id, User.concat, User.count)
),
[
@@ -3726,7 +3654,7 @@ class ExternalColumnsTest(QueryTest):
eq_(
list(
sess.query(Address, ua)
- .select_entity_from(join(Address, ua, "user"))
+ .select_entity_from(join(Address, ua, Address.user))
.with_entities(Address.id, ua.id, ua.concat, ua.count)
),
[
@@ -3782,7 +3710,7 @@ class ExternalColumnsTest(QueryTest):
def go():
o1 = (
sess.query(Order)
- .options(joinedload("address").joinedload("user"))
+ .options(joinedload(Order.address).joinedload(Address.user))
.get(1)
)
eq_(o1.address.user.count, 1)
@@ -3794,7 +3722,7 @@ class ExternalColumnsTest(QueryTest):
def go():
o1 = (
sess.query(Order)
- .options(joinedload("address").joinedload("user"))
+ .options(joinedload(Order.address).joinedload(Address.user))
.first()
)
eq_(o1.address.user.count, 1)
diff --git a/test/orm/test_generative.py b/test/orm/test_generative.py
index 1a40447a6..071346277 100644
--- a/test/orm/test_generative.py
+++ b/test/orm/test_generative.py
@@ -264,11 +264,13 @@ class RelationshipsTest(_fixtures.FixtureTest):
"""Query.join"""
User, Address = self.classes.User, self.classes.Address
+ Order = self.classes.Order
session = fixture_session()
q = (
session.query(User)
- .join("orders", "addresses")
+ .outerjoin(User.orders)
+ .outerjoin(Order.addresses)
.filter(Address.id == 1)
)
eq_([User(id=7)], q.all())
@@ -285,7 +287,8 @@ class RelationshipsTest(_fixtures.FixtureTest):
session = fixture_session()
q = (
session.query(User)
- .outerjoin("orders", "addresses")
+ .outerjoin(User.orders)
+ .outerjoin(Order.addresses)
.filter(sa.or_(Order.id == None, Address.id == 1))
) # noqa
eq_(set([User(id=7), User(id=8), User(id=10)]), set(q.all()))
@@ -303,7 +306,8 @@ class RelationshipsTest(_fixtures.FixtureTest):
q = (
session.query(User)
- .outerjoin("orders", "addresses")
+ .outerjoin(User.orders)
+ .outerjoin(Order.addresses)
.filter(sa.or_(Order.id == None, Address.id == 1))
) # noqa
eq_(q.count(), 4)
diff --git a/test/orm/test_joins.py b/test/orm/test_joins.py
index eb7dfd6f3..42f9b9aa1 100644
--- a/test/orm/test_joins.py
+++ b/test/orm/test_joins.py
@@ -226,8 +226,6 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
[
"relationship",
"relationship_only",
- "string_relationship",
- "string_relationship_only",
"none",
"explicit",
"table_none",
@@ -235,11 +233,6 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
],
[True, False],
)
- ).difference(
- [
- ("string_relationship", False),
- ("string_relationship_only", False),
- ]
),
argnames="onclause_type, use_legacy",
)
@@ -256,12 +249,8 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
if onclause_type == "relationship":
q = q.join(Address, User.addresses)
- elif onclause_type == "string_relationship":
- q = q.join(Address, "addresses")
elif onclause_type == "relationship_only":
q = q.join(User.addresses)
- elif onclause_type == "string_relationship_only":
- q = q.join("addresses")
elif onclause_type == "none":
q = q.join(Address)
elif onclause_type == "explicit":
diff --git a/test/orm/test_lazy_relations.py b/test/orm/test_lazy_relations.py
index 457cfee4e..2bea9b110 100644
--- a/test/orm/test_lazy_relations.py
+++ b/test/orm/test_lazy_relations.py
@@ -658,14 +658,14 @@ class LazyTest(_fixtures.FixtureTest):
[Order(id=1), Order(id=5)],
fixture_session()
.query(closed_mapper)
- .with_parent(user, property="closed_orders")
+ .with_parent(user, property=User.closed_orders)
.all(),
)
eq_(
[Order(id=3)],
fixture_session()
.query(open_mapper)
- .with_parent(user, property="open_orders")
+ .with_parent(user, property=User.open_orders)
.all(),
)
@@ -720,7 +720,7 @@ class LazyTest(_fixtures.FixtureTest):
eq_(
self.static.item_keyword_result[0:2],
- q.join("keywords").filter(keywords.c.name == "red").all(),
+ q.join(Item.keywords).filter(keywords.c.name == "red").all(),
)
def test_uses_get(self):
diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py
index 6c8b26c71..7d9e6f9c3 100644
--- a/test/orm/test_mapper.py
+++ b/test/orm/test_mapper.py
@@ -1498,7 +1498,7 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
session = fixture_session()
q = (
session.query(Item)
- .join("keywords")
+ .join(Item.keywords)
.distinct()
.filter(Keyword.name == "red")
)
@@ -2376,7 +2376,7 @@ class RequirementsTest(fixtures.MappedTest):
h1.h2s.extend([H2("abc"), H2("def")])
s.flush()
- h1s = s.query(H1).options(sa.orm.joinedload("h2s")).all()
+ h1s = s.query(H1).options(sa.orm.joinedload(H1.h2s)).all()
eq_(len(h1s), 5)
self.assert_unordered_result(
@@ -2394,15 +2394,15 @@ class RequirementsTest(fixtures.MappedTest):
{"h2s": (H2, [{"value": "def"}])},
)
- h1s = s.query(H1).options(sa.orm.joinedload("h3s")).all()
+ h1s = s.query(H1).options(sa.orm.joinedload(H1.h3s)).all()
eq_(len(h1s), 5)
h1s = (
s.query(H1)
.options(
- sa.orm.joinedload("t6a").joinedload("h1b"),
- sa.orm.joinedload("h2s"),
- sa.orm.joinedload("h3s").joinedload("h1s"),
+ sa.orm.joinedload(H1.t6a).joinedload(H6.h1b),
+ sa.orm.joinedload(H1.h2s),
+ sa.orm.joinedload(H1.h3s).joinedload(H3.h1s),
)
.all()
)
@@ -3151,13 +3151,13 @@ class ConfigureOrNotConfigureTest(_fixtures.FixtureTest, AssertsCompiledSQL):
if use_bound:
stmt = select(User).options(
- Load(User).load_only("name"),
+ Load(User).load_only(User.name),
)
is_true(um.configured)
else:
stmt = select(User).options(
- load_only("name"),
+ load_only(User.name),
)
is_false(um.configured)
diff --git a/test/orm/test_merge.py b/test/orm/test_merge.py
index 7d61a8722..3b97bd5a5 100644
--- a/test/orm/test_merge.py
+++ b/test/orm/test_merge.py
@@ -1211,7 +1211,9 @@ class MergeTest(_fixtures.FixtureTest):
sess.commit()
sess2 = fixture_session()
- u2 = sess2.query(User).options(sa.orm.joinedload("addresses")).get(7)
+ u2 = (
+ sess2.query(User).options(sa.orm.joinedload(User.addresses)).get(7)
+ )
sess3 = fixture_session()
u3 = sess3.merge(u2, load=False) # noqa
diff --git a/test/orm/test_of_type.py b/test/orm/test_of_type.py
index bc32e322d..bdf7ab859 100644
--- a/test/orm/test_of_type.py
+++ b/test/orm/test_of_type.py
@@ -81,7 +81,8 @@ class _PolymorphicTestBase(object):
sess = fixture_session()
eq_(
sess.query(Company)
- .join(Company.employees.of_type(Engineer), "machines")
+ .join(Company.employees.of_type(Engineer))
+ .join(Engineer.machines)
.filter(Machine.name.ilike("%thinkpad%"))
.all(),
[self.c1],
diff --git a/test/orm/test_options.py b/test/orm/test_options.py
index ebbbe738d..1a2a5ba70 100644
--- a/test/orm/test_options.py
+++ b/test/orm/test_options.py
@@ -509,15 +509,6 @@ class OptionsTest(PathTest, QueryTest):
strategy_options._UnboundLoad.joinedload, arg, True, {}
)
- def test_get_path_one_level_string(self):
- User = self.classes.User
-
- sess = fixture_session()
- q = sess.query(User)
-
- opt = self._option_fixture("addresses")
- self._assert_path_result(opt, q, [(User, "addresses")])
-
def test_get_path_one_level_attribute(self):
User = self.classes.User
@@ -545,33 +536,13 @@ class OptionsTest(PathTest, QueryTest):
def test_get_path_one_level_with_unrelated(self):
Order = self.classes.Order
+ User = self.classes.User
sess = fixture_session()
q = sess.query(Order)
- opt = self._option_fixture("addresses")
+ opt = self._option_fixture(User.addresses)
self._assert_path_result(opt, q, [])
- def test_path_multilevel_string(self):
- Item, User, Order = (
- self.classes.Item,
- self.classes.User,
- self.classes.Order,
- )
-
- sess = fixture_session()
- q = sess.query(User)
-
- opt = self._option_fixture("orders.items.keywords")
- self._assert_path_result(
- opt,
- q,
- [
- (User, "orders"),
- (User, "orders", Order, "items"),
- (User, "orders", Order, "items", Item, "keywords"),
- ],
- )
-
def test_path_multilevel_attribute(self):
Item, User, Order = (
self.classes.Item,
@@ -593,21 +564,6 @@ class OptionsTest(PathTest, QueryTest):
],
)
- def test_with_current_matching_string(self):
- Item, User, Order = (
- self.classes.Item,
- self.classes.User,
- self.classes.Order,
- )
-
- sess = fixture_session()
- q = sess.query(Item)._with_current_path(
- self._make_path_registry([User, "orders", Order, "items"])
- )
-
- opt = self._option_fixture("orders.items.keywords")
- self._assert_path_result(opt, q, [(Item, "keywords")])
-
def test_with_current_matching_attribute(self):
Item, User, Order = (
self.classes.Item,
@@ -623,24 +579,6 @@ class OptionsTest(PathTest, QueryTest):
opt = self._option_fixture(User.orders, Order.items, Item.keywords)
self._assert_path_result(opt, q, [(Item, "keywords")])
- def test_with_current_nonmatching_string(self):
- Item, User, Order = (
- self.classes.Item,
- self.classes.User,
- self.classes.Order,
- )
-
- sess = fixture_session()
- q = sess.query(Item)._with_current_path(
- self._make_path_registry([User, "orders", Order, "items"])
- )
-
- opt = self._option_fixture("keywords")
- self._assert_path_result(opt, q, [])
-
- opt = self._option_fixture("items.keywords")
- self._assert_path_result(opt, q, [])
-
def test_with_current_nonmatching_attribute(self):
Item, User, Order = (
self.classes.Item,
@@ -923,14 +861,6 @@ class OptionsTest(PathTest, QueryTest):
q = sess.query(Item, Order)
self._assert_path_result(opt, q, [(Order, "items")])
- def test_multi_entity_opt_on_string(self):
- Item = self.classes.Item
- Order = self.classes.Order
- opt = self._option_fixture("items")
- sess = fixture_session()
- q = sess.query(Item, Order)
- self._assert_path_result(opt, q, [])
-
def test_multi_entity_no_mapped_entities(self):
Item = self.classes.Item
Order = self.classes.Order
@@ -955,28 +885,11 @@ class OptionsTest(PathTest, QueryTest):
Order = self.classes.Order
sess = fixture_session()
q = sess.query(User)
- opt = self._option_fixture(User.orders).joinedload("items")
+ opt = self._option_fixture(User.orders).joinedload(Order.items)
self._assert_path_result(
opt, q, [(User, "orders"), (User, "orders", Order, "items")]
)
- def test_chained_plus_dotted(self):
- User = self.classes.User
- Order = self.classes.Order
- Item = self.classes.Item
- sess = fixture_session()
- q = sess.query(User)
- opt = self._option_fixture("orders.items").joinedload("keywords")
- self._assert_path_result(
- opt,
- q,
- [
- (User, "orders"),
- (User, "orders", Order, "items"),
- (User, "orders", Order, "items", Item, "keywords"),
- ],
- )
-
def test_chained_plus_multi(self):
User = self.classes.User
Order = self.classes.Order
@@ -984,7 +897,7 @@ class OptionsTest(PathTest, QueryTest):
sess = fixture_session()
q = sess.query(User)
opt = self._option_fixture(User.orders, Order.items).joinedload(
- "keywords"
+ Item.keywords
)
self._assert_path_result(
opt,
@@ -1055,47 +968,21 @@ class OptionsNoPropTest(_fixtures.FixtureTest):
run_inserts = None
run_deletes = None
- def test_option_with_mapper_basestring(self):
- Item = self.classes.Item
-
- self._assert_option([Item], "keywords")
-
def test_option_with_mapper_PropCompatator(self):
Item = self.classes.Item
self._assert_option([Item], Item.keywords)
- def test_option_with_mapper_then_column_basestring(self):
- Item = self.classes.Item
-
- self._assert_option([Item, Item.id], "keywords")
-
def test_option_with_mapper_then_column_PropComparator(self):
Item = self.classes.Item
self._assert_option([Item, Item.id], Item.keywords)
- def test_option_with_column_then_mapper_basestring(self):
- Item = self.classes.Item
-
- self._assert_option([Item.id, Item], "keywords")
-
def test_option_with_column_then_mapper_PropComparator(self):
Item = self.classes.Item
self._assert_option([Item.id, Item], Item.keywords)
- def test_option_with_column_basestring(self):
- Item = self.classes.Item
-
- message = (
- "Query has only expression-based entities - can't "
- 'find property named "keywords".'
- )
- self._assert_eager_with_just_column_exception(
- Item.id, "keywords", message
- )
-
def test_option_with_column_PropComparator(self):
Item = self.classes.Item
@@ -1118,81 +1005,6 @@ class OptionsNoPropTest(_fixtures.FixtureTest):
"the root entities to the target attribute. ",
)
- def test_option_against_nonexistent_basestring(self):
- Item = self.classes.Item
- self._assert_eager_with_entity_exception(
- [Item],
- (joinedload("foo"),),
- 'Can\'t find property named "foo" on mapped class '
- "Item->items in this Query.",
- )
-
- def test_option_against_nonexistent_twolevel_basestring(self):
- Item = self.classes.Item
- self._assert_eager_with_entity_exception(
- [Item],
- (joinedload("keywords.foo"),),
- 'Can\'t find property named "foo" on mapped class '
- "Keyword->keywords in this Query.",
- )
-
- def test_option_against_nonexistent_twolevel_chained(self):
- Item = self.classes.Item
- self._assert_eager_with_entity_exception(
- [Item],
- (joinedload("keywords").joinedload("foo"),),
- 'Can\'t find property named "foo" on mapped class '
- "Keyword->keywords in this Query.",
- )
-
- @testing.fails_if(
- lambda: True,
- "PropertyOption doesn't yet check for relation/column on end result",
- )
- def test_option_against_non_relation_basestring(self):
- Item = self.classes.Item
- Keyword = self.classes.Keyword
- self._assert_eager_with_entity_exception(
- [Keyword, Item],
- (joinedload("keywords"),),
- r"Attribute 'keywords' of entity 'Mapper\|Keyword\|keywords' "
- "does not refer to a mapped entity",
- )
-
- @testing.fails_if(
- lambda: True,
- "PropertyOption doesn't yet check for relation/column on end result",
- )
- def test_option_against_multi_non_relation_basestring(self):
- Item = self.classes.Item
- Keyword = self.classes.Keyword
- self._assert_eager_with_entity_exception(
- [Keyword, Item],
- (joinedload("keywords"),),
- r"Attribute 'keywords' of entity 'Mapper\|Keyword\|keywords' "
- "does not refer to a mapped entity",
- )
-
- def test_option_against_wrong_entity_type_basestring(self):
- Item = self.classes.Item
- self._assert_loader_strategy_exception(
- [Item],
- (joinedload("id").joinedload("keywords"),),
- 'Can\'t apply "joined loader" strategy to property "Item.id", '
- 'which is a "column property"; this loader strategy is '
- 'intended to be used with a "relationship property".',
- )
-
- def test_col_option_against_relationship_basestring(self):
- Item = self.classes.Item
- self._assert_loader_strategy_exception(
- [Item],
- (load_only("keywords"),),
- 'Can\'t apply "column loader" strategy to property '
- '"Item.keywords", which is a "relationship property"; this '
- 'loader strategy is intended to be used with a "column property".',
- )
-
def test_load_only_against_multi_entity_attr(self):
User = self.classes.User
Item = self.classes.Item
@@ -1217,37 +1029,6 @@ class OptionsNoPropTest(_fixtures.FixtureTest):
'loader strategy is intended to be used with a "column property".',
)
- def test_option_against_multi_non_relation_twolevel_basestring(self):
- Item = self.classes.Item
- Keyword = self.classes.Keyword
- self._assert_loader_strategy_exception(
- [Keyword, Item],
- (joinedload("id").joinedload("keywords"),),
- 'Can\'t apply "joined loader" strategy to property "Keyword.id", '
- 'which is a "column property"; this loader strategy is intended '
- 'to be used with a "relationship property".',
- )
-
- def test_option_against_multi_nonexistent_basestring(self):
- Item = self.classes.Item
- Keyword = self.classes.Keyword
- self._assert_eager_with_entity_exception(
- [Keyword, Item],
- (joinedload("description"),),
- 'Can\'t find property named "description" on mapped class '
- "Keyword->keywords in this Query.",
- )
-
- def test_option_against_multi_no_entities_basestring(self):
- Item = self.classes.Item
- Keyword = self.classes.Keyword
- self._assert_eager_with_entity_exception(
- [Keyword.id, Item.id],
- (joinedload("keywords"),),
- r"Query has only expression-based entities - can't find property "
- 'named "keywords".',
- )
-
def test_option_against_wrong_multi_entity_type_attr_one(self):
Item = self.classes.Item
Keyword = self.classes.Keyword
@@ -1467,22 +1248,6 @@ class OptionsNoPropTestInh(_Polymorphic):
._compile_state,
)
- def test_missing_str_attr_of_type_subclass(self):
- s = fixture_session()
-
- assert_raises_message(
- sa.exc.ArgumentError,
- r'Can\'t find property named "manager_name" on '
- r"mapped class Engineer->engineers in this Query.$",
- s.query(Company)
- .options(
- joinedload(Company.employees.of_type(Engineer)).load_only(
- "manager_name"
- )
- )
- ._compile_state,
- )
-
def test_missing_attr_of_type_wpoly_subclass(self):
s = fixture_session()
@@ -1883,35 +1648,6 @@ class SubOptionsTest(PathTest, QueryTest):
sess = fixture_session()
self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
- def test_four_strings(self):
- User, Address, Order, Item, SubItem, Keyword = self.classes(
- "User", "Address", "Order", "Item", "SubItem", "Keyword"
- )
- sub_opt = joinedload("orders").options(
- defer("description"),
- joinedload("items").options(
- joinedload("keywords").options(defer("name")),
- defer("description"),
- ),
- )
- non_sub_opts = [
- joinedload(User.orders),
- defaultload(User.orders).defer(Order.description),
- defaultload(User.orders).joinedload(Order.items),
- defaultload(User.orders)
- .defaultload(Order.items)
- .joinedload(Item.keywords),
- defaultload(User.orders)
- .defaultload(Order.items)
- .defer(Item.description),
- defaultload(User.orders)
- .defaultload(Order.items)
- .defaultload(Item.keywords)
- .defer(Keyword.name),
- ]
- sess = fixture_session()
- self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
-
def test_five(self):
User, Address, Order, Item, SubItem, Keyword = self.classes(
"User", "Address", "Order", "Item", "SubItem", "Keyword"
@@ -1924,18 +1660,6 @@ class SubOptionsTest(PathTest, QueryTest):
sess = fixture_session()
self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
- def test_five_strings(self):
- User, Address, Order, Item, SubItem, Keyword = self.classes(
- "User", "Address", "Order", "Item", "SubItem", "Keyword"
- )
- sub_opt = joinedload("orders").options(load_only("description"))
- non_sub_opts = [
- joinedload(User.orders),
- defaultload(User.orders).load_only(Order.description),
- ]
- sess = fixture_session()
- self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
-
def test_invalid_one(self):
User, Address, Order, Item, SubItem = self.classes(
"User", "Address", "Order", "Item", "SubItem"
@@ -1956,26 +1680,6 @@ class SubOptionsTest(PathTest, QueryTest):
sess = fixture_session()
self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
- def test_invalid_two(self):
- User, Address, Order, Item, SubItem = self.classes(
- "User", "Address", "Order", "Item", "SubItem"
- )
-
- # these options are "invalid", in that User.orders -> Item.keywords
- # is not a path. However, the "normal" option is not generating
- # an error for now, which is bad, but we're testing here only that
- # it works the same way, so there you go. If and when we make this
- # case raise, then both cases should raise in the same way.
- sub_opt = joinedload("orders").options(
- joinedload("keywords"), joinedload("items")
- )
- non_sub_opts = [
- joinedload(User.orders).joinedload(Item.keywords),
- defaultload(User.orders).joinedload(Order.items),
- ]
- sess = fixture_session()
- self._assert_opts(sess.query(User), sub_opt, non_sub_opts)
-
def test_not_implemented_fromload(self):
User, Address, Order, Item, SubItem = self.classes(
"User", "Address", "Order", "Item", "SubItem"
@@ -2030,7 +1734,7 @@ class MapperOptionsTest(_fixtures.FixtureTest):
u = (
sess.query(User)
.order_by(User.id)
- .options(sa.orm.joinedload("adlist"))
+ .options(sa.orm.joinedload(User.adlist))
.filter_by(name="jack")
).one()
eq_(u.adlist, [self.static.user_address_result[0].addresses[0]])
diff --git a/test/orm/test_pickled.py b/test/orm/test_pickled.py
index e33ec9a5c..e6f15c47b 100644
--- a/test/orm/test_pickled.py
+++ b/test/orm/test_pickled.py
@@ -345,8 +345,10 @@ class PickleTest(fixtures.MappedTest):
u1 = (
sess.query(User)
.options(
- sa.orm.defer("name"),
- sa.orm.defer("addresses.email_address"),
+ sa.orm.defer(User.name),
+ sa.orm.defaultload(User.addresses).defer(
+ Address.email_address
+ ),
)
.get(u1.id)
)
@@ -496,13 +498,11 @@ class PickleTest(fixtures.MappedTest):
@testing.requires.non_broken_pickle
@testing.combinations(
lambda User: sa.orm.joinedload(User.addresses),
- lambda: sa.orm.joinedload("addresses"),
- lambda: sa.orm.defer("name"),
lambda User: sa.orm.defer(User.name),
- lambda Address: sa.orm.joinedload("addresses").joinedload(
+ lambda Address: sa.orm.joinedload(User.addresses).joinedload(
Address.dingaling
),
- lambda: sa.orm.joinedload("addresses").raiseload("*"),
+ lambda: sa.orm.joinedload(User.addresses).raiseload("*"),
lambda: sa.orm.raiseload("*"),
)
def test_unbound_options(self, test_case):
@@ -518,15 +518,15 @@ class PickleTest(fixtures.MappedTest):
@testing.requires.non_broken_pickle
@testing.combinations(
lambda User: sa.orm.Load(User).joinedload(User.addresses),
- lambda User: sa.orm.Load(User).joinedload("addresses"),
- lambda User: sa.orm.Load(User).joinedload("addresses").raiseload("*"),
- lambda User: sa.orm.Load(User).defer("name"),
+ lambda User: sa.orm.Load(User)
+ .joinedload(User.addresses)
+ .raiseload("*"),
lambda User: sa.orm.Load(User).defer(User.name),
lambda User, Address: sa.orm.Load(User)
- .joinedload("addresses")
+ .joinedload(User.addresses)
.joinedload(Address.dingaling),
lambda User, Address: sa.orm.Load(User)
- .joinedload("addresses", innerjoin=True)
+ .joinedload(User.addresses, innerjoin=True)
.joinedload(Address.dingaling),
)
def test_bound_options(self, test_case):
@@ -548,10 +548,8 @@ class PickleTest(fixtures.MappedTest):
for opt in [
sa.orm.joinedload(User.addresses),
- sa.orm.joinedload("addresses"),
- sa.orm.defer("name"),
sa.orm.defer(User.name),
- sa.orm.joinedload("addresses").joinedload(Address.dingaling),
+ sa.orm.joinedload(User.addresses).joinedload(Address.dingaling),
]:
context = sess.query(User).options(opt)._compile_context()
opt = [
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index 3e58f211c..c9353f551 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -1340,7 +1340,7 @@ class GetTest(QueryTest):
s = fixture_session()
- q = s.query(User).join("addresses").filter(Address.user_id == 8)
+ q = s.query(User).join(User.addresses).filter(Address.user_id == 8)
assert_raises(sa_exc.InvalidRequestError, q.get, 7)
assert_raises(
sa_exc.InvalidRequestError,
@@ -1361,7 +1361,7 @@ class GetTest(QueryTest):
s.query(User).get(7)
- q = s.query(User).join("addresses").filter(Address.user_id == 8)
+ q = s.query(User).join(User.addresses).filter(Address.user_id == 8)
assert_raises(sa_exc.InvalidRequestError, q.get, 7)
def test_unique_param_names(self):
@@ -1428,6 +1428,7 @@ class GetTest(QueryTest):
def test_populate_existing(self):
User, Address = self.classes.User, self.classes.Address
+ Order = self.classes.Order
s = fixture_session(autoflush=False)
@@ -1457,13 +1458,15 @@ class GetTest(QueryTest):
# eager load does
s.query(User).options(
- joinedload("addresses"), joinedload("orders").joinedload("items")
+ joinedload(User.addresses),
+ joinedload(User.orders).joinedload(Order.items),
).populate_existing().all()
assert u.addresses[0].email_address == "jack@bean.com"
assert u.orders[1].items[2].description == "item 5"
def test_populate_existing_future(self):
User, Address = self.classes.User, self.classes.Address
+ Order = self.classes.Order
s = fixture_session(autoflush=False)
@@ -1500,8 +1503,8 @@ class GetTest(QueryTest):
stmt = (
select(User)
.options(
- joinedload("addresses"),
- joinedload("orders").joinedload("items"),
+ joinedload(User.addresses),
+ joinedload(User.orders).joinedload(Order.items),
)
.execution_options(populate_existing=True)
)
@@ -1545,7 +1548,7 @@ class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
q = testing.resolve_lambda(test_case, User=User, s=s)
- assert_raises(sa_exc.InvalidRequestError, q.join, "addresses")
+ assert_raises(sa_exc.InvalidRequestError, q.join, User.addresses)
assert_raises(sa_exc.InvalidRequestError, q.filter, User.name == "ed")
@@ -1557,7 +1560,7 @@ class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
assert_raises(sa_exc.InvalidRequestError, q.having, "foo")
- q.enable_assertions(False).join("addresses")
+ q.enable_assertions(False).join(User.addresses)
q.enable_assertions(False).filter(User.name == "ed")
q.enable_assertions(False).order_by("foo")
q.enable_assertions(False).group_by("foo")
@@ -1570,7 +1573,7 @@ class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
q = s.query(User).select_from(users)
assert_raises(sa_exc.InvalidRequestError, q.select_from, users)
- q = s.query(User).join("addresses")
+ q = s.query(User).join(User.addresses)
assert_raises(sa_exc.InvalidRequestError, q.select_from, users)
q = s.query(User).order_by(User.id)
@@ -3360,13 +3363,13 @@ class FilterTest(QueryTest, AssertsCompiledSQL):
# test that the contents are not adapted by the aliased join
ua = aliased(Address)
assert [User(id=7), User(id=8)] == sess.query(User).join(
- ua, "addresses"
+ ua, User.addresses
).filter(
~User.addresses.any(Address.email_address == "fred@fred.com")
).all()
assert [User(id=10)] == sess.query(User).outerjoin(
- ua, "addresses"
+ ua, User.addresses
).filter(~User.addresses.any()).all()
def test_any_doesnt_overcorrelate(self):
@@ -3378,7 +3381,7 @@ class FilterTest(QueryTest, AssertsCompiledSQL):
# test that any() doesn't overcorrelate
assert [User(id=7), User(id=8)] == sess.query(User).join(
- "addresses"
+ User.addresses
).filter(
~User.addresses.any(Address.email_address == "fred@fred.com")
).all()
@@ -3417,7 +3420,7 @@ class FilterTest(QueryTest, AssertsCompiledSQL):
# test has() doesn't overcorrelate
assert [Address(id=2), Address(id=3), Address(id=4)] == sess.query(
Address
- ).join("user").filter(
+ ).join(Address.user).filter(
Address.user.has(User.name.like("%ed%"), id=8)
).order_by(
Address.id
@@ -3427,7 +3430,7 @@ class FilterTest(QueryTest, AssertsCompiledSQL):
ua = aliased(User)
assert [Address(id=2), Address(id=3), Address(id=4)] == sess.query(
Address
- ).join(ua, "user").filter(
+ ).join(ua, Address.user).filter(
Address.user.has(User.name.like("%ed%"), id=8)
).order_by(
Address.id
@@ -4409,7 +4412,7 @@ class AggregateTest(QueryTest):
sess = fixture_session()
assert [User(name="ed", id=8)] == sess.query(User).order_by(
User.id
- ).group_by(User).join("addresses").having(
+ ).group_by(User).join(User.addresses).having(
func.count(Address.id) > 2
).all()
@@ -4417,7 +4420,7 @@ class AggregateTest(QueryTest):
User(name="jack", id=7),
User(name="fred", id=9),
] == sess.query(User).order_by(User.id).group_by(User).join(
- "addresses"
+ User.addresses
).having(
func.count(Address.id) < 2
).all()
@@ -4828,7 +4831,7 @@ class DistinctTest(QueryTest, AssertsCompiledSQL):
subq = (
sess.query(User, Address.email_address)
- .join("addresses")
+ .join(User.addresses)
.distinct()
.subquery()
)
@@ -4850,7 +4853,7 @@ class DistinctTest(QueryTest, AssertsCompiledSQL):
sess = fixture_session()
q = (
sess.query(User, Address.email_address)
- .join("addresses")
+ .join(User.addresses)
.distinct()
)
@@ -4875,9 +4878,9 @@ class DistinctTest(QueryTest, AssertsCompiledSQL):
# test that it works on embedded joinedload/LIMIT subquery
q = (
sess.query(User)
- .join("addresses")
+ .join(User.addresses)
.distinct()
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.order_by(desc(Address.email_address))
.limit(2)
)
@@ -5227,9 +5230,9 @@ class DistinctTest(QueryTest, AssertsCompiledSQL):
q = (
sess.query(User)
- .join("addresses")
+ .join(User.addresses)
.distinct(Address.email_address)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.order_by(desc(Address.email_address))
.limit(2)
)
@@ -5407,7 +5410,7 @@ class YieldTest(_fixtures.FixtureTest):
User = self.classes.User
sess = fixture_session()
- q = sess.query(User).options(joinedload("addresses")).yield_per(1)
+ q = sess.query(User).options(joinedload(User.addresses)).yield_per(1)
assert_raises_message(
sa_exc.InvalidRequestError,
"Can't use yield_per with eager loaders that require "
@@ -5420,7 +5423,7 @@ class YieldTest(_fixtures.FixtureTest):
User = self.classes.User
sess = fixture_session()
- q = sess.query(User).options(subqueryload("addresses")).yield_per(1)
+ q = sess.query(User).options(subqueryload(User.addresses)).yield_per(1)
assert_raises_message(
sa_exc.InvalidRequestError,
"Can't use yield_per with eager loaders that require "
@@ -5455,7 +5458,7 @@ class YieldTest(_fixtures.FixtureTest):
sess = fixture_session()
q = (
sess.query(User)
- .options(subqueryload("addresses"))
+ .options(subqueryload(User.addresses))
.enable_eagerloads(False)
.yield_per(1)
)
@@ -5463,7 +5466,7 @@ class YieldTest(_fixtures.FixtureTest):
q = (
sess.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.enable_eagerloads(False)
.yield_per(1)
)
@@ -5475,7 +5478,7 @@ class YieldTest(_fixtures.FixtureTest):
sess = fixture_session()
q = (
sess.query(Address)
- .options(lazyload("*"), joinedload("user"))
+ .options(lazyload("*"), joinedload(Address.user))
.yield_per(1)
.filter_by(id=1)
)
@@ -6154,7 +6157,7 @@ class TextTest(QueryTest, AssertsCompiledSQL):
q = (
s.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.order_by(desc("name"))
.limit(1)
)
@@ -6172,7 +6175,7 @@ class TextTest(QueryTest, AssertsCompiledSQL):
q = (
s.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.order_by("name")
.limit(1)
)
@@ -6190,7 +6193,7 @@ class TextTest(QueryTest, AssertsCompiledSQL):
self.assert_compile(
s.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.order_by("users_name")
.limit(1),
"SELECT anon_1.users_id AS anon_1_users_id, "
@@ -6209,7 +6212,7 @@ class TextTest(QueryTest, AssertsCompiledSQL):
# however! this works (again?)
eq_(
s.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.order_by("users_name")
.first(),
User(name="chuck", addresses=[]),
@@ -6222,7 +6225,7 @@ class TextTest(QueryTest, AssertsCompiledSQL):
self.assert_compile(
s.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.order_by(desc("users_name"))
.limit(1),
"SELECT anon_1.users_id AS anon_1_users_id, "
@@ -6241,7 +6244,7 @@ class TextTest(QueryTest, AssertsCompiledSQL):
# however! this works (again?)
eq_(
s.query(User)
- .options(joinedload("addresses"))
+ .options(joinedload(User.addresses))
.order_by(desc("users_name"))
.first(),
User(name="jack", addresses=[Address()]),
@@ -6260,7 +6263,7 @@ class TextTest(QueryTest, AssertsCompiledSQL):
q = sess.query(User, Address.email_address.label("email_address"))
result = (
- q.join("addresses")
+ q.join(User.addresses)
.options(joinedload(User.orders))
.order_by("email_address desc")
.limit(1)
@@ -6330,13 +6333,6 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
] == o
# test with explicit property
- o = sess.query(Order).with_parent(u1, property="orders").all()
- assert [
- Order(description="order 1"),
- Order(description="order 3"),
- Order(description="order 5"),
- ] == o
-
o = sess.query(Order).with_parent(u1, property=User.orders).all()
assert [
Order(description="order 1"),
@@ -6385,7 +6381,7 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
sess = fixture_session()
u1 = sess.query(User).get(7)
q = sess.query(User, Address).filter(
- with_parent(u1, "addresses", from_entity=Address)
+ with_parent(u1, User.addresses, from_entity=Address)
)
self.assert_compile(
q,
@@ -6404,7 +6400,7 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
sess = fixture_session()
u1 = sess.query(User).get(7)
q = sess.query(User, Address).with_parent(
- u1, "addresses", from_entity=Address
+ u1, User.addresses, from_entity=Address
)
self.assert_compile(
q,
@@ -6440,7 +6436,7 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
sess = fixture_session()
u1 = sess.query(User).get(7)
a1 = aliased(Address)
- q = sess.query(a1).with_parent(u1, "addresses")
+ q = sess.query(a1).with_parent(u1, User.addresses)
self.assert_compile(
q,
"SELECT addresses_1.id AS addresses_1_id, "
@@ -6530,7 +6526,7 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
q = sess.query(User)
u1 = q.filter_by(name="jack").one()
utrans = User(id=u1.id)
- o = sess.query(Order).with_parent(utrans, "orders")
+ o = sess.query(Order).with_parent(utrans, User.orders)
eq_(
[
Order(description="order 1"),
@@ -6540,7 +6536,7 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
o.all(),
)
- o = sess.query(Order).filter(with_parent(utrans, "orders"))
+ o = sess.query(Order).filter(with_parent(utrans, User.orders))
eq_(
[
Order(description="order 1"),
@@ -6559,11 +6555,11 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
opending = Order(id=20, user_id=o1.user_id)
sess.add(opending)
eq_(
- sess.query(User).with_parent(opending, "user").one(),
+ sess.query(User).with_parent(opending, Order.user).one(),
User(id=o1.user_id),
)
eq_(
- sess.query(User).filter(with_parent(opending, "user")).one(),
+ sess.query(User).filter(with_parent(opending, Order.user)).one(),
User(id=o1.user_id),
)
@@ -6576,7 +6572,7 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
opending = Order(user_id=o1.user_id)
sess.add(opending)
eq_(
- sess.query(User).with_parent(opending, "user").one(),
+ sess.query(User).with_parent(opending, Order.user).one(),
User(id=o1.user_id),
)
@@ -6587,8 +6583,8 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
sess = fixture_session()
u1, u2 = sess.query(User).order_by(User.id)[0:2]
- q1 = sess.query(Address).with_parent(u1, "addresses")
- q2 = sess.query(Address).with_parent(u2, "addresses")
+ q1 = sess.query(Address).with_parent(u1, User.addresses)
+ q2 = sess.query(Address).with_parent(u2, User.addresses)
self.assert_compile(
q1.union(q2),
@@ -6614,7 +6610,10 @@ class ParentTest(QueryTest, AssertsCompiledSQL):
self.assert_compile(
sess.query(Address).filter(
- or_(with_parent(u1, "addresses"), with_parent(u2, "addresses"))
+ or_(
+ with_parent(u1, User.addresses),
+ with_parent(u2, User.addresses),
+ )
),
"SELECT addresses.id AS addresses_id, addresses.user_id AS "
"addresses_user_id, addresses.email_address AS "
@@ -6832,7 +6831,7 @@ class WithTransientOnNone(_fixtures.FixtureTest, AssertsCompiledSQL):
sess = fixture_session()
- q = sess.query(User).with_parent(Address(user_id=None), "user")
+ q = sess.query(User).with_parent(Address(user_id=None), Address.user)
with expect_warnings("Got None for value of column"):
self.assert_compile(
q,
@@ -6847,7 +6846,7 @@ class WithTransientOnNone(_fixtures.FixtureTest, AssertsCompiledSQL):
s = fixture_session()
q = s.query(User).with_parent(
- Address(user_id=None, email_address=None), "special_user"
+ Address(user_id=None, email_address=None), Address.special_user
)
with expect_warnings("Got None for value of column"):
@@ -7025,35 +7024,6 @@ class SynonymTest(QueryTest, AssertsCompiledSQL):
self.assert_sql_count(testing.db, go, 1)
- def test_options_syn_of_syn_string(self):
- User, Order = self.classes.User, self.classes.Order
-
- s = fixture_session()
-
- def go():
- result = (
- s.query(User)
- .filter_by(name="jack")
- .options(joinedload("orders_syn_2"))
- .all()
- )
- eq_(
- result,
- [
- User(
- id=7,
- name="jack",
- orders=[
- Order(description="order 1"),
- Order(description="order 3"),
- Order(description="order 5"),
- ],
- )
- ],
- )
-
- self.assert_sql_count(testing.db, go, 1)
-
def test_joins(self):
User, Order = self.classes.User, self.classes.Order
@@ -7084,12 +7054,12 @@ class SynonymTest(QueryTest, AssertsCompiledSQL):
Order, User = self.classes.Order, self.classes.User
for nameprop, orderprop in (
- ("name", "orders"),
- ("name_syn", "orders"),
- ("name", "orders_syn"),
- ("name", "orders_syn_2"),
- ("name_syn", "orders_syn"),
- ("name_syn", "orders_syn_2"),
+ ("name", User.orders),
+ ("name_syn", User.orders),
+ ("name", User.orders_syn),
+ ("name", User.orders_syn_2),
+ ("name_syn", User.orders_syn),
+ ("name_syn", User.orders_syn_2),
):
with fixture_session() as sess:
q = sess.query(User)
diff --git a/test/orm/test_relationships.py b/test/orm/test_relationships.py
index a25e39c82..2547a981a 100644
--- a/test/orm/test_relationships.py
+++ b/test/orm/test_relationships.py
@@ -358,7 +358,7 @@ class M2ODontOverwriteFKTest(fixtures.MappedTest):
sess.commit()
# test that was broken by #3060
- a1 = sess.query(A).options(joinedload("b")).first()
+ a1 = sess.query(A).options(joinedload(A.b)).first()
a1.bid = b1.id
sess.flush()
@@ -6081,7 +6081,11 @@ class RaiseLoadTest(_fixtures.FixtureTest):
users,
properties=dict(addresses=relationship(Address, lazy="raise")),
)
- q = fixture_session().query(User).options(sa.orm.lazyload("addresses"))
+ q = (
+ fixture_session()
+ .query(User)
+ .options(sa.orm.lazyload(User.addresses))
+ )
result = [None]
def go():
@@ -6110,7 +6114,7 @@ class RaiseLoadTest(_fixtures.FixtureTest):
a1 = (
s.query(Address)
.filter_by(id=1)
- .options(sa.orm.raiseload("user"))
+ .options(sa.orm.raiseload(Address.user))
.first()
)
@@ -6138,7 +6142,7 @@ class RaiseLoadTest(_fixtures.FixtureTest):
a1 = (
s.query(Address)
.filter_by(id=1)
- .options(sa.orm.raiseload("user", sql_only=True))
+ .options(sa.orm.raiseload(Address.user, sql_only=True))
.first()
)
@@ -6157,7 +6161,7 @@ class RaiseLoadTest(_fixtures.FixtureTest):
a1 = (
s.query(Address)
.filter_by(id=1)
- .options(sa.orm.raiseload("user", sql_only=True))
+ .options(sa.orm.raiseload(Address.user, sql_only=True))
.first()
)
assert "user" not in a1.__dict__
@@ -6189,7 +6193,7 @@ class RaiseLoadTest(_fixtures.FixtureTest):
a1 = (
s.query(Address)
.filter_by(id=1)
- .options(sa.orm.raiseload("user", sql_only=True))
+ .options(sa.orm.raiseload(Address.user, sql_only=True))
.first()
)
diff --git a/test/orm/test_selectin_relations.py b/test/orm/test_selectin_relations.py
index ceaead9c4..e3d852e68 100644
--- a/test/orm/test_selectin_relations.py
+++ b/test/orm/test_selectin_relations.py
@@ -352,7 +352,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
def go():
eq_(
self.static.item_keyword_result[0:2],
- q.join("keywords").filter(Keyword.name == "red").all(),
+ q.join(Item.keywords).filter(Keyword.name == "red").all(),
)
self.assert_sql_count(testing.db, go, 2)
@@ -386,7 +386,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
ka = aliased(Keyword)
eq_(
self.static.item_keyword_result[0:2],
- (q.join(ka, "keywords").filter(ka.name == "red")).all(),
+ (q.join(ka, Item.keywords).filter(ka.name == "red")).all(),
)
self.assert_sql_count(testing.db, go, 2)
@@ -1571,7 +1571,7 @@ class LoadOnExistingTest(_fixtures.FixtureTest):
a2 = u1.addresses[0]
a2.email_address = "foo"
sess.query(User).options(
- selectinload("addresses").selectinload("dingaling")
+ selectinload(User.addresses).selectinload(Address.dingaling)
).filter_by(id=8).all()
assert u1.addresses[-1] is a1
for a in u1.addresses:
@@ -1590,7 +1590,7 @@ class LoadOnExistingTest(_fixtures.FixtureTest):
o1 = Order()
u1.orders.append(o1)
sess.query(User).options(
- selectinload("orders").selectinload("items")
+ selectinload(User.orders).selectinload(Order.items)
).filter_by(id=7).all()
for o in u1.orders:
if o is not o1:
@@ -1604,11 +1604,11 @@ class LoadOnExistingTest(_fixtures.FixtureTest):
u1 = (
sess.query(User)
.filter_by(id=8)
- .options(selectinload("addresses"))
+ .options(selectinload(User.addresses))
.one()
)
sess.query(User).filter_by(id=8).options(
- selectinload("addresses").selectinload("dingaling")
+ selectinload(User.addresses).selectinload(Address.dingaling)
).first()
assert "dingaling" in u1.addresses[0].__dict__
@@ -1618,11 +1618,11 @@ class LoadOnExistingTest(_fixtures.FixtureTest):
u1 = (
sess.query(User)
.filter_by(id=7)
- .options(selectinload("orders"))
+ .options(selectinload(User.orders))
.one()
)
sess.query(User).filter_by(id=7).options(
- selectinload("orders").selectinload("items")
+ selectinload(User.orders).selectinload(Order.items)
).first()
assert "items" in u1.orders[0].__dict__
@@ -2784,7 +2784,7 @@ class SelfReferentialTest(fixtures.MappedTest):
eq_(
Node(data="n1", children=[Node(data="n11"), Node(data="n12")]),
sess.query(Node)
- .options(undefer("data"))
+ .options(undefer(Node.data))
.order_by(Node.id)
.first(),
)
@@ -2797,7 +2797,10 @@ class SelfReferentialTest(fixtures.MappedTest):
eq_(
Node(data="n1", children=[Node(data="n11"), Node(data="n12")]),
sess.query(Node)
- .options(undefer("data"), undefer("children.data"))
+ .options(
+ undefer(Node.data),
+ defaultload(Node.children).undefer(Node.data),
+ )
.first(),
)
@@ -2832,7 +2835,9 @@ class SelfReferentialTest(fixtures.MappedTest):
sess.query(Node)
.filter_by(data="n1")
.order_by(Node.id)
- .options(selectinload("children").selectinload("children"))
+ .options(
+ selectinload(Node.children).selectinload(Node.children)
+ )
.first()
)
eq_(
diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py
index 70d8d19bd..25ebb9ebe 100644
--- a/test/orm/test_subquery_relations.py
+++ b/test/orm/test_subquery_relations.py
@@ -10,6 +10,7 @@ from sqlalchemy.orm import aliased
from sqlalchemy.orm import backref
from sqlalchemy.orm import clear_mappers
from sqlalchemy.orm import close_all_sessions
+from sqlalchemy.orm import defaultload
from sqlalchemy.orm import defer
from sqlalchemy.orm import deferred
from sqlalchemy.orm import joinedload
@@ -443,7 +444,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
def go():
eq_(
self.static.item_keyword_result[0:2],
- q.join("keywords").filter(Keyword.name == "red").all(),
+ q.join(Item.keywords).filter(Keyword.name == "red").all(),
)
self.assert_sql_count(testing.db, go, 2)
@@ -477,7 +478,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
ka = aliased(Keyword)
eq_(
self.static.item_keyword_result[0:2],
- (q.join(ka, "keywords").filter(ka.name == "red")).all(),
+ (q.join(ka, Item.keywords).filter(ka.name == "red")).all(),
)
self.assert_sql_count(testing.db, go, 2)
@@ -1598,7 +1599,7 @@ class LoadOnExistingTest(_fixtures.FixtureTest):
a2 = u1.addresses[0]
a2.email_address = "foo"
sess.query(User).options(
- subqueryload("addresses").subqueryload("dingaling")
+ subqueryload(User.addresses).subqueryload(Address.dingaling)
).filter_by(id=8).all()
assert u1.addresses[-1] is a1
for a in u1.addresses:
@@ -1617,7 +1618,7 @@ class LoadOnExistingTest(_fixtures.FixtureTest):
o1 = Order()
u1.orders.append(o1)
sess.query(User).options(
- subqueryload("orders").subqueryload("items")
+ subqueryload(User.orders).subqueryload(Order.items)
).filter_by(id=7).all()
for o in u1.orders:
if o is not o1:
@@ -1631,11 +1632,11 @@ class LoadOnExistingTest(_fixtures.FixtureTest):
u1 = (
sess.query(User)
.filter_by(id=8)
- .options(subqueryload("addresses"))
+ .options(subqueryload(User.addresses))
.one()
)
sess.query(User).filter_by(id=8).options(
- subqueryload("addresses").subqueryload("dingaling")
+ subqueryload(User.addresses).subqueryload(Address.dingaling)
).first()
assert "dingaling" in u1.addresses[0].__dict__
@@ -1645,11 +1646,11 @@ class LoadOnExistingTest(_fixtures.FixtureTest):
u1 = (
sess.query(User)
.filter_by(id=7)
- .options(subqueryload("orders"))
+ .options(subqueryload(User.orders))
.one()
)
sess.query(User).filter_by(id=7).options(
- subqueryload("orders").subqueryload("items")
+ subqueryload(User.orders).subqueryload(Order.items)
).first()
assert "items" in u1.orders[0].__dict__
@@ -2536,7 +2537,7 @@ class SelfReferentialTest(fixtures.MappedTest):
eq_(
Node(data="n1", children=[Node(data="n11"), Node(data="n12")]),
sess.query(Node)
- .options(undefer("data"))
+ .options(undefer(Node.data))
.order_by(Node.id)
.first(),
)
@@ -2549,7 +2550,10 @@ class SelfReferentialTest(fixtures.MappedTest):
eq_(
Node(data="n1", children=[Node(data="n11"), Node(data="n12")]),
sess.query(Node)
- .options(undefer("data"), undefer("children.data"))
+ .options(
+ undefer(Node.data),
+ defaultload(Node.children).undefer(Node.data),
+ )
.first(),
)
@@ -2584,7 +2588,9 @@ class SelfReferentialTest(fixtures.MappedTest):
sess.query(Node)
.filter_by(data="n1")
.order_by(Node.id)
- .options(subqueryload("children").subqueryload("children"))
+ .options(
+ subqueryload(Node.children).subqueryload(Node.children)
+ )
.first()
)
eq_(
@@ -3189,7 +3195,9 @@ class JoinedNoLoadConflictTest(fixtures.DeclarativeMappedTest):
# Parent->subqueryload->Child->joinedload->parent->noload->children.
# the actual subqueryload has to emit *after* we've started populating
# Parent->subqueryload->child.
- parent = s.query(Parent).options([subqueryload("children")]).first()
+ parent = (
+ s.query(Parent).options([subqueryload(Parent.children)]).first()
+ )
eq_(parent.children, [Child(name="c1")])
diff --git a/test/orm/test_unitofwork.py b/test/orm/test_unitofwork.py
index afba9d953..d95565cd4 100644
--- a/test/orm/test_unitofwork.py
+++ b/test/orm/test_unitofwork.py
@@ -234,7 +234,7 @@ class UnicodeSchemaTest(fixtures.MappedTest):
new_a1 = (
session.query(A)
- .options(sa.orm.joinedload("t2s"))
+ .options(sa.orm.joinedload(A.t2s))
.filter(t1.c.a == a1.a)
).one()
assert new_a1.a == a1.a