--- /dev/null
+.. change::
+ :tags: bug, orm, regression
+ :tickets: 6762
+
+ Fixed regression which appeared in version 1.4.3 due to :ticket:`6060`
+ where rules that limit ORM adaptation of derived selectables interfered
+ with other ORM-adaptation based cases, in this case when applying
+ adaptations for a :func:`_orm.with_polymorphic` against a mapping which
+ uses a :func:`_orm.column_property` which in turn makes use of a scalar
+ select that includes a :func:`_orm.aliased` object of the mapped table.
if isinstance(col, FromClause) and not isinstance(
col, functions.FunctionElement
):
- if self.adapt_from_selectables:
- for adp in self.adapt_from_selectables:
- if adp.is_derived_from(col):
- break
- else:
- return None
if self.selectable.is_derived_from(col):
+ if self.adapt_from_selectables:
+ for adp in self.adapt_from_selectables:
+ if adp.is_derived_from(col):
+ break
+ else:
+ return None
return self.selectable
elif isinstance(col, Alias) and isinstance(
col.element, TableClause
from sqlalchemy import testing
from sqlalchemy import Unicode
from sqlalchemy import util
+from sqlalchemy.orm import aliased
from sqlalchemy.orm import class_mapper
from sqlalchemy.orm import column_property
from sqlalchemy.orm import contains_eager
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import with_polymorphic
from sqlalchemy.orm.interfaces import MANYTOONE
+from sqlalchemy.testing import AssertsCompiledSQL
from sqlalchemy.testing import AssertsExecutionResults
from sqlalchemy.testing import eq_
from sqlalchemy.testing import fixtures
)
+class ColPropWAliasJoinedToBaseTest(
+ AssertsCompiledSQL, fixtures.DeclarativeMappedTest
+):
+ """test #6762"""
+
+ __dialect__ = "default"
+ run_create_tables = None
+
+ @classmethod
+ def setup_classes(cls):
+ Base = cls.DeclarativeBasic
+
+ class Content(Base):
+
+ __tablename__ = "content"
+
+ id = Column(Integer, primary_key=True)
+ type = Column(String)
+ container_id = Column(Integer, ForeignKey("folder.id"))
+
+ __mapper_args__ = {"polymorphic_on": type}
+
+ class Folder(Content):
+
+ __tablename__ = "folder"
+
+ id = Column(ForeignKey("content.id"), primary_key=True)
+
+ __mapper_args__ = {
+ "polymorphic_identity": "f",
+ "inherit_condition": id == Content.id,
+ }
+
+ _alias = aliased(Content)
+
+ Content.__mapper__.add_property(
+ "count_children",
+ column_property(
+ select(func.count("*"))
+ .where(_alias.container_id == Content.id)
+ .scalar_subquery()
+ ),
+ )
+
+ def test_alias_omitted(self):
+ Content = self.classes.Content
+ Folder = self.classes.Folder
+
+ sess = fixture_session()
+
+ entity = with_polymorphic(Content, [Folder], innerjoin=True)
+
+ self.assert_compile(
+ sess.query(entity),
+ "SELECT content.id AS content_id, content.type AS content_type, "
+ "content.container_id AS content_container_id, "
+ "(SELECT count(:count_2) AS count_1 FROM content AS content_1 "
+ "WHERE content_1.container_id = content.id) AS anon_1, "
+ "folder.id AS folder_id FROM content "
+ "JOIN folder ON folder.id = content.id",
+ )
+
+
class SelfRefWPolyJoinedLoadTest(fixtures.DeclarativeMappedTest):
"""test #6495"""
{"param_1": 5, "param_2": 10},
)
- def test_aliasedselect_to_aliasedselect_join_nested_table(self):
+ @testing.combinations((True,), (False,), argnames="use_adapt_from")
+ def test_aliasedselect_to_aliasedselect_join_nested_table(
+ self, use_adapt_from
+ ):
+ """test the logic in clauseadapter regarding not traversing aliases.
+
+ adapt_from_selectables case added to test #6762, which is a regression
+ from #6060
+
+ """
s1 = select(t1).alias("foo")
s2 = select(s1).limit(5).offset(10).alias()
talias = t1.alias("bar")
j = s1.outerjoin(talias, s1.c.col1 == talias.c.col1)
+ if use_adapt_from:
+ vis = sql_util.ClauseAdapter(s2, adapt_from_selectables=[s1])
+ else:
+ vis = sql_util.ClauseAdapter(s2)
self.assert_compile(
- sql_util.ClauseAdapter(s2).traverse(j).select(),
+ vis.traverse(j).select(),
"SELECT anon_1.col1, anon_1.col2, "
"anon_1.col3, bar.col1 AS col1_1, bar.col2 AS col2_1, "
"bar.col3 AS col3_1 "