--- /dev/null
+.. change::
+ :tags: bug, orm, regression
+ :tickets: 9217
+
+ Fixed regression when using :meth:`_sql.Select.from_statement` in an ORM
+ context, where matching of columns to SQL labels based on name alone was
+ disabled for ORM-statements that weren't fully textual. This would prevent
+ arbitrary SQL expressions with column-name labels from matching up to the
+ entity to be loaded, which previously would work within the 1.4
+ and previous series, so the previous behavior has been restored.
# those columns completely, don't interfere with the compiler
# at all; just in ORM land, use an adapter to convert from
# our ORM columns to whatever columns are in the statement,
- # before we look in the result row. If the inner statement is
- # not ORM enabled, assume looser col matching based on name
- statement_is_orm = (
- self.statement._propagate_attrs.get(
- "compile_state_plugin", None
- )
- == "orm"
- )
+ # before we look in the result row. Always adapt on names
+ # to accept cases such as issue #9217.
self._from_obj_alias = ORMStatementAdapter(
_TraceAdaptRole.ADAPT_FROM_STATEMENT,
self.statement,
- adapt_on_names=not statement_is_orm,
+ adapt_on_names=True,
)
return self
from sqlalchemy.testing import AssertsCompiledSQL
from sqlalchemy.testing import eq_
from sqlalchemy.testing import fixtures
+from sqlalchemy.testing import in_
from sqlalchemy.testing import is_
from sqlalchemy.testing.fixtures import fixture_session
from sqlalchemy.testing.schema import Column
eq_(q.all(), expected)
+ def test_unrelated_column(self):
+ """Test for 9217"""
+
+ User = self.classes.User
+
+ q = select(User.id, func.lower("SANDY").label("name")).where(
+ User.id == 7
+ )
+
+ s = select(User).from_statement(q)
+ sess = fixture_session()
+ res = sess.scalars(s).one()
+ in_("name", res.__dict__)
+ eq_(res.name, "sandy")
+
def test_expression_selectable_matches_mzero(self):
User, Address = self.classes.User, self.classes.Address