]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
repair mapper sort
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 20 Jan 2022 14:31:42 +0000 (09:31 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 20 Jan 2022 14:33:20 +0000 (09:33 -0500)
Fixed issue in :meth:`_orm.Session.bulk_save_mappings` where the sorting
that takes place when the ``preserve_order`` parameter is set to False
would sort partially on ``Mapper`` objects, which is rejected in Python
3.11.

Also uses typing_extensions for NotRequired as this symbol
does not seem to be in Python 3.11.0a4 yet. (2.0 only)

Fixes: #7591
Change-Id: I24a62f2322ad7dac5d8e4a00853f8a9408877c9c
(cherry picked from commit 8d3d934c16a91adcdc7f374c01761b18fbba74d9)

doc/build/changelog/unreleased_14/7591.rst [new file with mode: 0644]
lib/sqlalchemy/orm/session.py

diff --git a/doc/build/changelog/unreleased_14/7591.rst b/doc/build/changelog/unreleased_14/7591.rst
new file mode 100644 (file)
index 0000000..4ecf983
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, orm
+    :tickets: 7591
+
+    Fixed issue in :meth:`_orm.Session.bulk_save_mappings` where the sorting
+    that takes place when the ``preserve_order`` parameter is set to False
+    would sort partially on ``Mapper`` objects, which is rejected in Python
+    3.11.
+
index 49e8060d0823ea24a715c7ba9ec9ab857b701a28..d5a80953d6ed69f35f86c842583a321938a72c35 100644 (file)
@@ -3602,14 +3602,24 @@ class Session(_SessionClassMethods):
 
         """
 
-        def key(state):
-            return (state.mapper, state.key is not None)
-
         obj_states = (attributes.instance_state(obj) for obj in objects)
+
         if not preserve_order:
-            obj_states = sorted(obj_states, key=key)
+            # the purpose of this sort is just so that common mappers
+            # and persistence states are grouped together, so that groupby
+            # will return a single group for a particular type of mapper.
+            # it's not trying to be deterministic beyond that.
+            obj_states = sorted(
+                obj_states,
+                key=lambda state: (id(state.mapper), state.key is not None),
+            )
 
-        for (mapper, isupdate), states in itertools.groupby(obj_states, key):
+        def grouping_key(state):
+            return (state.mapper, state.key is not None)
+
+        for (mapper, isupdate), states in itertools.groupby(
+            obj_states, grouping_key
+        ):
             self._bulk_save_mappings(
                 mapper,
                 states,