]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fixed regression when using from_statement in orm context.
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 1 Feb 2023 23:16:39 +0000 (18:16 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 3 Feb 2023 14:34:14 +0000 (09:34 -0500)
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.

Fixes: #9217
Change-Id: I5f7ab9710a96a98241388883365e56d308b4daf2

doc/build/changelog/unreleased_20/9217.rst [new file with mode: 0644]
lib/sqlalchemy/orm/context.py
test/orm/test_froms.py

diff --git a/doc/build/changelog/unreleased_20/9217.rst b/doc/build/changelog/unreleased_20/9217.rst
new file mode 100644 (file)
index 0000000..5768357
--- /dev/null
@@ -0,0 +1,10 @@
+.. 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.
index 890f3382b964d57bf8185e0165716324fe594d0f..0e631e66f73da21f34294c9a72a1aa5a6e491f93 100644 (file)
@@ -731,19 +731,13 @@ class ORMFromStatementCompileState(ORMCompileState):
             # 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
index 85c950876b29af7972e44d7626773297f3d302d1..e24062469f25b6704f7c3753ba16b29b4056e46e 100644 (file)
@@ -36,6 +36,7 @@ from sqlalchemy.testing import assert_raises_message
 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
@@ -2726,6 +2727,21 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
 
             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