diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-01-20 09:31:42 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-01-20 14:46:09 -0500 |
| commit | 769dc1d2cb217c66918bec01718aa657a0239040 (patch) | |
| tree | 6e61ced520057bdfea5154b07277379b7de9077e /lib/sqlalchemy | |
| parent | 5677ea7f1b8de3cba5c8c0fbf70e3840a5a9889f (diff) | |
| download | sqlalchemy-769dc1d2cb217c66918bec01718aa657a0239040.tar.gz | |
repair mapper sort
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.
For interim 3.11 support, adds the git main build of greenlet
for Python 3.11
Fixes: #7591
Change-Id: I24a62f2322ad7dac5d8e4a00853f8a9408877c9c
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/orm/session.py | 20 | ||||
| -rw-r--r-- | lib/sqlalchemy/util/typing.py | 7 |
2 files changed, 17 insertions, 10 deletions
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index aa642e65e..cf47ee729 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -3389,14 +3389,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, diff --git a/lib/sqlalchemy/util/typing.py b/lib/sqlalchemy/util/typing.py index e2d42db6e..5767d258b 100644 --- a/lib/sqlalchemy/util/typing.py +++ b/lib/sqlalchemy/util/typing.py @@ -6,6 +6,8 @@ from typing import Type from typing import TypeVar from typing import Union +from typing_extensions import NotRequired # noqa + from . import compat _T = TypeVar("_T", bound=Any) @@ -26,11 +28,6 @@ else: from typing_extensions import Concatenate # noqa from typing_extensions import ParamSpec # noqa -if compat.py311: - from typing import NotRequired # noqa -else: - from typing_extensions import NotRequired # noqa - _T = TypeVar("_T") |
