--- /dev/null
+.. change::
+ :tags: bug, regression, orm
+ :tickets: 6172
+
+ Fixed regression where the :func:`_orm.joinedload` loader strategy would
+ not successfully joinedload to a mapper that is mapper against a
+ :class:`.CTE` construct.
self._suffixes = _suffixes
super(CTE, self)._init(selectable, name=name)
+ def _populate_column_collection(self):
+ if self._cte_alias is not None:
+ self._cte_alias._generate_fromclause_column_proxies(self)
+ else:
+ self.element._generate_fromclause_column_proxies(self)
+
def alias(self, name=None, flat=False):
"""Return an :class:`_expression.Alias` of this
:class:`_expression.CTE`.
self.assert_sql_count(testing.db, go, 1)
+ @testing.combinations(
+ ("plain",), ("cte", testing.requires.ctes), ("subquery",), id_="s"
+ )
+ def test_map_to_cte_subq(self, type_):
+ User, Address = self.classes("User", "Address")
+ users, addresses = self.tables("users", "addresses")
+
+ if type_ == "plain":
+ target = users
+ elif type_ == "cte":
+ target = select(users).cte()
+ elif type_ == "subquery":
+ target = select(users).subquery()
+
+ mapper(
+ User,
+ target,
+ properties={"addresses": relationship(Address, backref="user")},
+ )
+ mapper(Address, addresses)
+
+ sess = fixture_session()
+
+ q = (
+ sess.query(Address)
+ .options(joinedload(Address.user))
+ .order_by(Address.id)
+ )
+ eq_(q.all(), self.static.address_user_result)
+
def test_no_false_hits(self):
"""Eager loaders don't interpret main table columns as
part of their eager load."""
.all(),
)
+ @testing.combinations(
+ ("plain",), ("cte", testing.requires.ctes), ("subquery",), id_="s"
+ )
+ def test_map_to_cte_subq(self, type_):
+ User, Address = self.classes("User", "Address")
+ users, addresses = self.tables("users", "addresses")
+
+ if type_ == "plain":
+ target = users
+ elif type_ == "cte":
+ target = select(users).cte()
+ elif type_ == "subquery":
+ target = select(users).subquery()
+
+ mapper(
+ User,
+ target,
+ properties={"addresses": relationship(Address, backref="user")},
+ )
+ mapper(Address, addresses)
+
+ sess = fixture_session()
+
+ q = sess.query(Address).order_by(Address.id)
+ eq_(q.all(), self.static.address_user_result)
+
def test_many_to_many(self):
keywords, items, item_keywords, Keyword, Item = (
self.tables.keywords,
else:
self.assert_sql_count(testing.db, go, 6)
+ @testing.combinations(
+ ("plain",), ("cte", testing.requires.ctes), ("subquery",), id_="s"
+ )
+ def test_map_to_cte_subq(self, type_):
+ User, Address = self.classes("User", "Address")
+ users, addresses = self.tables("users", "addresses")
+
+ if type_ == "plain":
+ target = users
+ elif type_ == "cte":
+ target = select(users).cte()
+ elif type_ == "subquery":
+ target = select(users).subquery()
+
+ mapper(
+ User,
+ target,
+ properties={"addresses": relationship(Address, backref="user")},
+ )
+ mapper(Address, addresses)
+
+ sess = fixture_session()
+
+ q = (
+ sess.query(Address)
+ .options(selectinload(Address.user))
+ .order_by(Address.id)
+ )
+ eq_(q.all(), self.static.address_user_result)
+
def test_limit(self):
"""Limit operations combined with lazy-load relationships."""
else:
self.assert_sql_count(testing.db, go, 6)
+ @testing.combinations(
+ ("plain",), ("cte", testing.requires.ctes), ("subquery",), id_="s"
+ )
+ def test_map_to_cte_subq(self, type_):
+ User, Address = self.classes("User", "Address")
+ users, addresses = self.tables("users", "addresses")
+
+ if type_ == "plain":
+ target = users
+ elif type_ == "cte":
+ target = select(users).cte()
+ elif type_ == "subquery":
+ target = select(users).subquery()
+
+ mapper(
+ User,
+ target,
+ properties={"addresses": relationship(Address, backref="user")},
+ )
+ mapper(Address, addresses)
+
+ sess = fixture_session()
+
+ q = (
+ sess.query(Address)
+ .options(subqueryload(Address.user))
+ .order_by(Address.id)
+ )
+ eq_(q.all(), self.static.address_user_result)
+
def test_limit(self):
"""Limit operations combined with lazy-load relationships."""
s1, "SELECT (SELECT table1.col1 FROM table1) AS foo"
)
+ @testing.combinations(("cte",), ("subquery",), argnames="type_")
+ @testing.combinations(
+ ("onelevel",), ("twolevel",), ("middle",), argnames="path"
+ )
+ @testing.combinations((True,), (False,), argnames="require_embedded")
+ def test_subquery_cte_correspondence(self, type_, require_embedded, path):
+ stmt = select(table1)
+
+ if type_ == "cte":
+ cte1 = stmt.cte()
+ elif type_ == "subquery":
+ cte1 = stmt.subquery()
+
+ if path == "onelevel":
+ is_(
+ cte1.corresponding_column(
+ table1.c.col1, require_embedded=require_embedded
+ ),
+ cte1.c.col1,
+ )
+ elif path == "twolevel":
+ cte2 = cte1.alias()
+
+ is_(
+ cte2.corresponding_column(
+ table1.c.col1, require_embedded=require_embedded
+ ),
+ cte2.c.col1,
+ )
+
+ elif path == "middle":
+ cte2 = cte1.alias()
+
+ is_(
+ cte2.corresponding_column(
+ cte1.c.col1, require_embedded=require_embedded
+ ),
+ cte2.c.col1,
+ )
+
def test_labels_anon_w_separate_key(self):
label = select(table1.c.col1).label(None)
label.key = "bar"