]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
we probably dont need ORDER BY for selectin_polymorphic
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 1 Jan 2026 16:39:45 +0000 (11:39 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 2 Jan 2026 14:58:19 +0000 (09:58 -0500)
Removed the ``ORDER BY`` clause from queries generated by
:func:`_orm.selectin_polymorphic` and the
:paramref:`_orm.Mapper.polymorphic_load` parameter set to ``"selectin"``.
The ``ORDER BY`` clause appears to have been an unnecessary implementation
artifact.

Fixes: #13060
Change-Id: If563844cbca54f507421d5dcd1ab67afdabb10fc

doc/build/changelog/migration_12.rst
doc/build/changelog/unreleased_21/13060.rst [new file with mode: 0644]
doc/build/orm/queryguide/inheritance.rst
lib/sqlalchemy/orm/mapper.py
test/orm/inheritance/test_poly_loading.py

index cd21d0879101affdd39bf83a5e19c1145b32782a..6e0340aa1316f93d7eb26001e95bcf33b09296d6 100644 (file)
@@ -202,7 +202,7 @@ are loaded with additional SELECT statements:
         employee.type AS employee_type,
         engineer.engineer_name AS engineer_engineer_name
     FROM employee JOIN engineer ON employee.id = engineer.id
-    WHERE employee.id IN (?, ?) ORDER BY employee.id
+    WHERE employee.id IN (?, ?)
     (1, 2)
 
     SELECT
@@ -211,7 +211,7 @@ are loaded with additional SELECT statements:
         employee.type AS employee_type,
         manager.manager_name AS manager_manager_name
     FROM employee JOIN manager ON employee.id = manager.id
-    WHERE employee.id IN (?) ORDER BY employee.id
+    WHERE employee.id IN (?)
     (3,)
 
 .. seealso::
diff --git a/doc/build/changelog/unreleased_21/13060.rst b/doc/build/changelog/unreleased_21/13060.rst
new file mode 100644 (file)
index 0000000..21d19c8
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, orm
+    :tickets: 13060
+
+    Removed the ``ORDER BY`` clause from queries generated by
+    :func:`_orm.selectin_polymorphic` and the
+    :paramref:`_orm.Mapper.polymorphic_load` parameter set to ``"selectin"``.
+    The ``ORDER BY`` clause appears to have been an unnecessary implementation
+    artifact.
index 063bdbfd3b0a471ccd68ce718bbb790d8c84ee55..d76edde3f3108a1774fb4fa523b0293676a23db9 100644 (file)
@@ -151,12 +151,12 @@ load columns local to both the ``Manager`` and ``Engineer`` subclasses::
     SELECT manager.id AS manager_id, employee.id AS employee_id,
     employee.type AS employee_type, manager.manager_name AS manager_manager_name
     FROM employee JOIN manager ON employee.id = manager.id
-    WHERE employee.id IN (?) ORDER BY employee.id
+    WHERE employee.id IN (?)
     [...] (1,)
     SELECT engineer.id AS engineer_id, employee.id AS employee_id,
     employee.type AS employee_type, engineer.engineer_info AS engineer_engineer_info
     FROM employee JOIN engineer ON employee.id = engineer.id
-    WHERE employee.id IN (?, ?) ORDER BY employee.id
+    WHERE employee.id IN (?, ?)
     [...] (2, 3)
     {stop}>>> print(objects)
     [Manager('Mr. Krabs'), Engineer('SpongeBob'), Engineer('Squidward')]
@@ -219,13 +219,13 @@ we only indicate the additional target subclasses we wish to load::
     employee.type AS employee_type,
     manager.manager_name AS manager_manager_name
     FROM employee JOIN manager ON employee.id = manager.id
-    WHERE employee.id IN (?) ORDER BY employee.id
+    WHERE employee.id IN (?)
     [...] (1,)
     SELECT engineer.id AS engineer_id, employee.id AS employee_id,
     employee.type AS employee_type,
     engineer.engineer_info AS engineer_engineer_info
     FROM employee JOIN engineer ON employee.id = engineer.id
-    WHERE employee.id IN (?, ?) ORDER BY employee.id
+    WHERE employee.id IN (?, ?)
     [...] (2, 3)
     {stop}company: Krusty Krab
     employees: [Manager('Mr. Krabs'), Engineer('SpongeBob'), Engineer('Squidward')]
@@ -270,7 +270,7 @@ this collection on all ``Manager`` objects, where the sub-attributes of
     [...] ()
     SELECT manager.id AS manager_id, employee.id AS employee_id, employee.type AS employee_type, manager.manager_name AS manager_manager_name
     FROM employee JOIN manager ON employee.id = manager.id
-    WHERE employee.id IN (?) ORDER BY employee.id
+    WHERE employee.id IN (?)
     [...] (1,)
     SELECT paperwork.manager_id, paperwork.id, paperwork.document_name
     FROM paperwork
@@ -278,7 +278,7 @@ this collection on all ``Manager`` objects, where the sub-attributes of
     [...] (1,)
     SELECT engineer.id AS engineer_id, employee.id AS employee_id, employee.type AS employee_type, engineer.engineer_info AS engineer_engineer_info
     FROM employee JOIN engineer ON employee.id = engineer.id
-    WHERE employee.id IN (?, ?) ORDER BY employee.id
+    WHERE employee.id IN (?, ?)
     [...] (2, 3)
     {stop}>>> print(objects[0])
     Manager('Mr. Krabs')
@@ -332,7 +332,7 @@ examples to load ``Company.employees``, also loading the attributes for the
     [...] (1,)
     SELECT manager.id AS manager_id, employee.id AS employee_id, employee.type AS employee_type, manager.manager_name AS manager_manager_name
     FROM employee JOIN manager ON employee.id = manager.id
-    WHERE employee.id IN (?) ORDER BY employee.id
+    WHERE employee.id IN (?)
     [...] (1,)
     SELECT paperwork.manager_id, paperwork.id, paperwork.document_name
     FROM paperwork
@@ -340,7 +340,7 @@ examples to load ``Company.employees``, also loading the attributes for the
     [...] (1,)
     SELECT engineer.id AS engineer_id, employee.id AS employee_id, employee.type AS employee_type, engineer.engineer_info AS engineer_engineer_info
     FROM employee JOIN engineer ON employee.id = engineer.id
-    WHERE employee.id IN (?, ?) ORDER BY employee.id
+    WHERE employee.id IN (?, ?)
     [...] (2, 3)
     {stop}company: Krusty Krab
     manager: Mr. Krabs paperwork: [Paperwork('Secret Recipes'), Paperwork('Krabby Patty Orders')]
index 88542491709e633517479f73302aea25259b265e..b8659b748cdd398fe7767b699a09e1cc28d8b1f4 100644 (file)
@@ -3846,17 +3846,16 @@ class Mapper(
             )
 
             in_expr = entity._adapter.traverse(in_expr)
-            primary_key = [entity._adapter.traverse(k) for k in primary_key]
             q = q.where(
                 in_expr.in_(sql.bindparam("primary_keys", expanding=True))
-            ).order_by(*primary_key)
+            )
         else:
             q = sql.select(self).set_label_style(
                 LABEL_STYLE_TABLENAME_PLUS_COL
             )
             q = q.where(
                 in_expr.in_(sql.bindparam("primary_keys", expanding=True))
-            ).order_by(*primary_key)
+            )
 
         return q, enable_opt, disable_opt
 
index 9bdb695e17d0e1c464d8e8f6d26d3d415e92b457..197155f433bbaa5d1b085fd4933270707df02142 100644 (file)
@@ -127,8 +127,7 @@ class BaseAndSubFixture:
                         "a.type AS a_type, "
                         "asub.asubdata AS asub_asubdata FROM a JOIN asub "
                         "ON a.id = asub.id "
-                        "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                        "ORDER BY a.id",
+                        "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                         {"primary_keys": [2]},
                     ),
                     CompiledSQL(
@@ -251,7 +250,7 @@ class ChunkingTest(
             "SELECT asub.id AS asub_id, a.id AS a_id, a.type AS a_type, "
             "asub.asubdata AS asub_asubdata FROM a JOIN asub "
             "ON a.id = asub.id WHERE a.id "
-            "IN (__[POSTCOMPILE_primary_keys]) ORDER BY a.id"
+            "IN (__[POSTCOMPILE_primary_keys])"
         )
         asserter.assert_(
             CompiledSQL(
@@ -297,8 +296,7 @@ class FixtureLoadTest(_Polymorphic, testing.AssertsExecutionResults):
                     "engineers.primary_language AS engineers_primary_language "
                     "FROM people JOIN engineers "
                     "ON people.person_id = engineers.person_id "
-                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY people.person_id",
+                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys])",
                     {"primary_keys": [1, 2, 5]},
                 ),
                 CompiledSQL(
@@ -309,8 +307,7 @@ class FixtureLoadTest(_Polymorphic, testing.AssertsExecutionResults):
                     "managers.manager_name AS managers_manager_name "
                     "FROM people JOIN managers "
                     "ON people.person_id = managers.person_id "
-                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY people.person_id",
+                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys])",
                     {"primary_keys": [3, 4]},
                 ),
             ),
@@ -356,8 +353,7 @@ class FixtureLoadTest(_Polymorphic, testing.AssertsExecutionResults):
                     "managers.manager_name AS managers_manager_name "
                     "FROM people JOIN managers "
                     "ON people.person_id = managers.person_id "
-                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY people.person_id",
+                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys])",
                     {"primary_keys": [3, 4]},
                 ),
                 CompiledSQL(
@@ -369,8 +365,7 @@ class FixtureLoadTest(_Polymorphic, testing.AssertsExecutionResults):
                     "engineers.primary_language AS engineers_primary_language "
                     "FROM people JOIN engineers "
                     "ON people.person_id = engineers.person_id "
-                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY people.person_id",
+                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys])",
                     {"primary_keys": [1, 2, 5]},
                 ),
             ),
@@ -420,8 +415,7 @@ class FixtureLoadTest(_Polymorphic, testing.AssertsExecutionResults):
                     "managers.manager_name AS managers_manager_name "
                     "FROM people JOIN managers "
                     "ON people.person_id = managers.person_id "
-                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY people.person_id",
+                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys])",
                     {"primary_keys": [3, 4]},
                 ),
                 CompiledSQL(
@@ -433,8 +427,7 @@ class FixtureLoadTest(_Polymorphic, testing.AssertsExecutionResults):
                     "engineers.primary_language AS engineers_primary_language "
                     "FROM people JOIN engineers "
                     "ON people.person_id = engineers.person_id "
-                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY people.person_id",
+                    "WHERE people.person_id IN (__[POSTCOMPILE_primary_keys])",
                     {"primary_keys": [1, 2, 5]},
                 ),
                 CompiledSQL(
@@ -498,8 +491,7 @@ class TestGeometries(GeometryFixtureBase):
                     "c.c_data AS c_c_data, c.e_data AS c_e_data, "
                     "c.d_data AS c_d_data "
                     "FROM a JOIN c ON a.id = c.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [1, 2]}],
                 ),
                 CompiledSQL(
@@ -507,8 +499,7 @@ class TestGeometries(GeometryFixtureBase):
                     "c.c_data AS c_c_data, "
                     "c.d_data AS c_d_data, c.e_data AS c_e_data "
                     "FROM a JOIN c ON a.id = c.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [1, 2]}],
                 ),
             ),
@@ -570,8 +561,7 @@ class TestGeometries(GeometryFixtureBase):
                     "a.type AS a_type, c.c_data AS c_c_data, "
                     "d.d_data AS d_d_data "
                     "FROM a JOIN c ON a.id = c.id JOIN d ON c.id = d.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [1]}],
                 ),
                 CompiledSQL(
@@ -579,8 +569,7 @@ class TestGeometries(GeometryFixtureBase):
                     "a.type AS a_type, c.c_data AS c_c_data, "
                     "e.e_data AS e_e_data "
                     "FROM a JOIN c ON a.id = c.id JOIN e ON c.id = e.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [2]}],
                 ),
             )
@@ -622,8 +611,7 @@ class TestGeometries(GeometryFixtureBase):
                     "a.type AS a_type, c.c_data AS c_c_data, "
                     "d.d_data AS d_d_data "
                     "FROM a JOIN c ON a.id = c.id JOIN d ON c.id = d.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [1]}],
                 ),
                 # only loads pk 2 - this is the filtering inside of do_load
@@ -631,8 +619,7 @@ class TestGeometries(GeometryFixtureBase):
                     "SELECT c.id AS c_id, a.id AS a_id, a.type AS a_type, "
                     "c.c_data AS c_c_data "
                     "FROM a JOIN c ON a.id = c.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [2]}],
                 ),
                 # no more SQL; if we hit pk 1 again, it would re-do the d here
@@ -677,7 +664,7 @@ class TestGeometries(GeometryFixtureBase):
             CompiledSQL(
                 "SELECT c.id AS c_id, a.id AS a_id, a.type AS a_type, "
                 "c.c_data AS c_c_data FROM a JOIN c ON a.id = c.id "
-                "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) ORDER BY a.id",
+                "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                 {"primary_keys": [1]},
             ),
         )
@@ -731,14 +718,14 @@ class TestGeometries(GeometryFixtureBase):
                 "SELECT d.id AS d_id, c.id AS c_id, a.id AS a_id, "
                 "a.type AS a_type, d.d_data AS d_d_data "
                 "FROM a JOIN c ON a.id = c.id JOIN d ON c.id = d.id "
-                "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) ORDER BY a.id",
+                "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                 [{"primary_keys": [1]}],
             ),
             CompiledSQL(
                 "SELECT e.id AS e_id, c.id AS c_id, a.id AS a_id, "
                 "a.type AS a_type, e.e_data AS e_e_data "
                 "FROM a JOIN c ON a.id = c.id JOIN e ON c.id = e.id "
-                "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) ORDER BY a.id",
+                "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                 [{"primary_keys": [2]}],
             ),
         )
@@ -787,8 +774,7 @@ class TestGeometries(GeometryFixtureBase):
                     "c.c_data AS c_c_data, c.e_data AS c_e_data, "
                     "c.d_data AS c_d_data "
                     "FROM a JOIN c ON a.id = c.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [1, 2]}],
                 ),
                 CompiledSQL(
@@ -796,8 +782,7 @@ class TestGeometries(GeometryFixtureBase):
                     "c.c_data AS c_c_data, c.d_data AS c_d_data, "
                     "c.e_data AS c_e_data "
                     "FROM a JOIN c ON a.id = c.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [1, 2]}],
                 ),
             ),
@@ -852,14 +837,13 @@ class TestGeometries(GeometryFixtureBase):
                     "SELECT c.id AS c_id, b.id AS b_id, a.id AS a_id, "
                     "a.type AS a_type, c.c_data AS c_c_data FROM a JOIN b "
                     "ON a.id = b.id JOIN c ON b.id = c.id WHERE a.id IN "
-                    "(__[POSTCOMPILE_primary_keys]) ORDER BY a.id",
+                    "(__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": c_pks}],
                 ),
                 CompiledSQL(
                     "SELECT b.id AS b_id, a.id AS a_id, a.type AS a_type, "
                     "b.b_data AS b_b_data FROM a JOIN b ON a.id = b.id "
-                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY a.id",
+                    "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": pks}],
                 ),
             ),
@@ -938,8 +922,7 @@ class TestGeometries(GeometryFixtureBase):
                         "e.id AS e_id, e.e_data AS e_e_data FROM a JOIN c "
                         "ON a.id = c.id LEFT OUTER JOIN d ON c.id = d.id "
                         "LEFT OUTER JOIN e ON c.id = e.id) AS poly "
-                        "WHERE poly.a_id IN (__[POSTCOMPILE_primary_keys]) "
-                        "ORDER BY poly.a_id",
+                        "WHERE poly.a_id IN (__[POSTCOMPILE_primary_keys])",
                         [{"primary_keys": [1, 2]}],
                     ),
                     CompiledSQL(
@@ -956,8 +939,7 @@ class TestGeometries(GeometryFixtureBase):
                         "e.e_data AS e_e_data FROM a JOIN c ON a.id = c.id "
                         "LEFT OUTER JOIN d ON c.id = d.id "
                         "LEFT OUTER JOIN e ON c.id = e.id) AS poly "
-                        "WHERE poly.a_id IN (__[POSTCOMPILE_primary_keys]) "
-                        "ORDER BY poly.a_id",
+                        "WHERE poly.a_id IN (__[POSTCOMPILE_primary_keys])",
                         [{"primary_keys": [1, 2]}],
                     ),
                 ),
@@ -977,24 +959,21 @@ class TestGeometries(GeometryFixtureBase):
                     CompiledSQL(
                         "SELECT c.id AS c_id, a.id AS a_id, a.type AS a_type, "
                         "c.c_data AS c_c_data FROM a JOIN c ON a.id = c.id "
-                        "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                        "ORDER BY a.id",
+                        "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                         [{"primary_keys": [1, 2]}],
                     ),
                     CompiledSQL(
                         "SELECT d.id AS d_id, c.id AS c_id, a.id AS a_id, "
                         "a.type AS a_type, d.d_data AS d_d_data FROM a "
                         "JOIN c ON a.id = c.id JOIN d ON c.id = d.id "
-                        "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                        "ORDER BY a.id",
+                        "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                         [{"primary_keys": [1]}],
                     ),
                     CompiledSQL(
                         "SELECT e.id AS e_id, c.id AS c_id, a.id AS a_id, "
                         "a.type AS a_type, e.e_data AS e_e_data FROM a "
                         "JOIN c ON a.id = c.id JOIN e ON c.id = e.id "
-                        "WHERE a.id IN (__[POSTCOMPILE_primary_keys]) "
-                        "ORDER BY a.id",
+                        "WHERE a.id IN (__[POSTCOMPILE_primary_keys])",
                         [{"primary_keys": [2]}],
                     ),
                 ),
@@ -1127,8 +1106,7 @@ class LoaderOptionsTest(
                     "child.type AS child_type "
                     "FROM child JOIN child_subclass1 "
                     "ON child.id = child_subclass1.id "
-                    "WHERE child.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY child.id",
+                    "WHERE child.id IN (__[POSTCOMPILE_primary_keys])",
                     [{"primary_keys": [1]}],
                 ),
             )
@@ -1177,8 +1155,7 @@ class LoaderOptionsTest(
                 "ON child.id = child_subclass1.id "
                 "LEFT OUTER JOIN other AS other_1 "
                 "ON child_subclass1.id = other_1.child_subclass_id "
-                "WHERE child.id IN (__[POSTCOMPILE_primary_keys]) "
-                "ORDER BY child.id",
+                "WHERE child.id IN (__[POSTCOMPILE_primary_keys])",
                 [{"primary_keys": [1]}],
             ),
         )
@@ -1523,16 +1500,14 @@ class NoBaseWPPlusAliasedTest(
                     "SELECT a.id AS a_id, baseclass.id AS baseclass_id, "
                     "a.thing1 AS a_thing1 FROM baseclass "
                     "JOIN a ON baseclass.id = a.id "
-                    "WHERE baseclass.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY baseclass.id",
+                    "WHERE baseclass.id IN (__[POSTCOMPILE_primary_keys])",
                     {"primary_keys": [1, 2, 5, 6]},
                 ),
                 CompiledSQL(
                     "SELECT b.id AS b_id, baseclass.id AS baseclass_id, "
                     "b.thing2 AS b_thing2 FROM baseclass "
                     "JOIN b ON baseclass.id = b.id "
-                    "WHERE baseclass.id IN (__[POSTCOMPILE_primary_keys]) "
-                    "ORDER BY baseclass.id",
+                    "WHERE baseclass.id IN (__[POSTCOMPILE_primary_keys])",
                     {"primary_keys": [3, 4, 7, 8]},
                 ),
             ),