summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/util.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-06-08 13:05:20 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-06-08 13:07:06 -0400
commit293b0e3dd8205185b84cd3baf2f078348437d245 (patch)
tree062f2c6e0c820a631df4d551d4385b9d67b5f18e /lib/sqlalchemy/orm/util.py
parent258d07e478eab9ee385f36a5c5fd56c56bf7dfea (diff)
downloadsqlalchemy-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.py28
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: