diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-06-08 13:05:20 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-06-08 13:07:06 -0400 |
commit | 293b0e3dd8205185b84cd3baf2f078348437d245 (patch) | |
tree | 062f2c6e0c820a631df4d551d4385b9d67b5f18e /lib/sqlalchemy/orm/util.py | |
parent | 258d07e478eab9ee385f36a5c5fd56c56bf7dfea (diff) | |
download | sqlalchemy-293b0e3dd8205185b84cd3baf2f078348437d245.tar.gz |
suppport with_loader_criteria pickling w/ fixed callable
Fixed issue where a :func:`_orm.with_loader_criteria` option could not be
pickled, as is necessary when it is carried along for propagation to lazy
loaders in conjunction with a caching scheme. Currently, the only form that
is supported as picklable is to pass the "where criteria" as a fixed
module-level callable function that produces a SQL expression. An ad-hoc
"lambda" can't be pickled, and a SQL expression object is usually not fully
picklable directly.
Fixes: #8109
Change-Id: I49fe69088b0c7e58a0f22c67d2ea4e33752a5a73
Diffstat (limited to 'lib/sqlalchemy/orm/util.py')
-rw-r--r-- | lib/sqlalchemy/orm/util.py | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index e1e78c99d..14a6bccb0 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -1138,6 +1138,8 @@ class _WrapUserEntity: """ + __slots__ = ("subject",) + def __init__(self, subject): self.subject = subject @@ -1171,6 +1173,7 @@ class LoaderCriteriaOption(CriteriaOption): "entity", "deferred_where_criteria", "where_criteria", + "_where_crit_orig", "include_aliases", "propagate_to_loaders", ) @@ -1190,6 +1193,8 @@ class LoaderCriteriaOption(CriteriaOption): include_aliases: bool propagate_to_loaders: bool + _where_crit_orig: Any + def __init__( self, entity_or_base: _EntityType[Any], @@ -1210,6 +1215,7 @@ class LoaderCriteriaOption(CriteriaOption): self.root_entity = None self.entity = entity + self._where_crit_orig = where_criteria if callable(where_criteria): if self.root_entity is not None: wrap_entity = self.root_entity @@ -1235,6 +1241,28 @@ class LoaderCriteriaOption(CriteriaOption): self.include_aliases = include_aliases self.propagate_to_loaders = propagate_to_loaders + @classmethod + def _unreduce( + cls, entity, where_criteria, include_aliases, propagate_to_loaders + ): + return LoaderCriteriaOption( + entity, + where_criteria, + include_aliases=include_aliases, + propagate_to_loaders=propagate_to_loaders, + ) + + def __reduce__(self): + return ( + LoaderCriteriaOption._unreduce, + ( + self.entity.class_ if self.entity else None, + self._where_crit_orig, + self.include_aliases, + self.propagate_to_loaders, + ), + ) + def _all_mappers(self) -> Iterator[Mapper[Any]]: if self.entity: |