diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-12-01 17:24:27 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-05-24 11:54:08 -0400 |
commit | dce8c7a125cb99fad62c76cd145752d5afefae36 (patch) | |
tree | 352dfa2c38005207ca64f45170bbba2c0f8c927e /lib/sqlalchemy/orm/attributes.py | |
parent | 1502b5b3e4e4b93021eb927a6623f288ef006ba6 (diff) | |
download | sqlalchemy-dce8c7a125cb99fad62c76cd145752d5afefae36.tar.gz |
Unify Query and select() , move all processing to compile phase
Convert Query to do virtually all compile state computation
in the _compile_context() phase, and organize it all
such that a plain select() construct may also be used as the
source of information in order to generate ORM query state.
This makes it such that Query is not needed except for
its additional methods like from_self() which are all to
be deprecated.
The construction of ORM state will occur beyond the
caching boundary when the new execution model is integrated.
future select() gains a working join() and filter_by() method.
as we continue to rebase and merge each commit in the steps,
callcounts continue to bump around. will have to look at
the final result when it's all in.
References: #5159
References: #4705
References: #4639
References: #4871
References: #5010
Change-Id: I19e05b3424b07114cce6c439b05198ac47f7ac10
Diffstat (limited to 'lib/sqlalchemy/orm/attributes.py')
-rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index ec706d4d8..7b4415bfe 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -49,6 +49,7 @@ from .. import event from .. import inspection from .. import util from ..sql import base as sql_base +from ..sql import roles from ..sql import visitors @@ -57,7 +58,8 @@ class QueryableAttribute( interfaces._MappedAttribute, interfaces.InspectionAttr, interfaces.PropComparator, - sql_base.HasCacheKey, + roles.JoinTargetRole, + sql_base.MemoizedHasCacheKey, ): """Base class for :term:`descriptor` objects that intercept attribute events on behalf of a :class:`.MapperProperty` @@ -107,12 +109,24 @@ class QueryableAttribute( self.dispatch._active_history = True _cache_key_traversal = [ - # ("class_", visitors.ExtendedInternalTraversal.dp_plain_obj), ("key", visitors.ExtendedInternalTraversal.dp_string), ("_parententity", visitors.ExtendedInternalTraversal.dp_multi), ("_of_type", visitors.ExtendedInternalTraversal.dp_multi), ] + def __reduce__(self): + # this method is only used in terms of the + # sqlalchemy.ext.serializer extension + return ( + _queryable_attribute_unreduce, + ( + self.key, + self._parententity.mapper.class_, + self._parententity, + self._parententity.entity, + ), + ) + @util.memoized_property def _supports_population(self): return self.impl.supports_population @@ -208,14 +222,14 @@ class QueryableAttribute( parententity=adapt_to_entity, ) - def of_type(self, cls): + def of_type(self, entity): return QueryableAttribute( self.class_, self.key, self.impl, - self.comparator.of_type(cls), + self.comparator.of_type(entity), self._parententity, - of_type=cls, + of_type=inspection.inspect(entity), ) def label(self, name): @@ -265,6 +279,15 @@ class QueryableAttribute( return self.comparator.property +def _queryable_attribute_unreduce(key, mapped_class, parententity, entity): + # this method is only used in terms of the + # sqlalchemy.ext.serializer extension + if parententity.is_aliased_class: + return entity._get_from_serialized(key, mapped_class, parententity) + else: + return getattr(entity, key) + + class InstrumentedAttribute(QueryableAttribute): """Class bound instrumented attribute which adds basic :term:`descriptor` methods. |