summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/mapper.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm/mapper.py')
-rw-r--r--lib/sqlalchemy/orm/mapper.py61
1 files changed, 48 insertions, 13 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index c05705b67..a6fb1039f 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -37,6 +37,8 @@ from .interfaces import _MappedAttribute
from .interfaces import EXT_SKIP
from .interfaces import InspectionAttr
from .interfaces import MapperProperty
+from .interfaces import ORMEntityColumnsClauseRole
+from .interfaces import ORMFromClauseRole
from .path_registry import PathRegistry
from .. import event
from .. import exc as sa_exc
@@ -70,7 +72,12 @@ _CONFIGURE_MUTEX = util.threading.RLock()
@inspection._self_inspects
@log.class_logger
-class Mapper(sql_base.HasCacheKey, InspectionAttr):
+class Mapper(
+ ORMFromClauseRole,
+ ORMEntityColumnsClauseRole,
+ sql_base.MemoizedHasCacheKey,
+ InspectionAttr,
+):
"""Define the correlation of class attributes to database table
columns.
@@ -2085,6 +2092,20 @@ class Mapper(sql_base.HasCacheKey, InspectionAttr):
return self._mappers_from_spec(*self.with_polymorphic)
@HasMemoized.memoized_attribute
+ def _post_inspect(self):
+ """This hook is invoked by attribute inspection.
+
+ E.g. when Query calls:
+
+ coercions.expect(roles.ColumnsClauseRole, ent, keep_inspect=True)
+
+ This allows the inspection process run a configure mappers hook.
+
+ """
+ if Mapper._new_mappers:
+ configure_mappers()
+
+ @HasMemoized.memoized_attribute
def _with_polymorphic_selectable(self):
if not self.with_polymorphic:
return self.persist_selectable
@@ -2207,12 +2228,16 @@ class Mapper(sql_base.HasCacheKey, InspectionAttr):
for table, columns in self._cols_by_table.items()
)
- # temporarily commented out until we fix an issue in the serializer
- # @_memoized_configured_property.method
+ @HasMemoized.memoized_instancemethod
def __clause_element__(self):
- return self.selectable # ._annotate(
- # {"parententity": self, "parentmapper": self}
- # )
+ return self.selectable._annotate(
+ {
+ "entity_namespace": self,
+ "parententity": self,
+ "parentmapper": self,
+ "compile_state_plugin": "orm",
+ }
+ )
@property
def selectable(self):
@@ -2386,6 +2411,10 @@ class Mapper(sql_base.HasCacheKey, InspectionAttr):
return self._filter_properties(descriptor_props.SynonymProperty)
+ @property
+ def entity_namespace(self):
+ return self.class_
+
@HasMemoized.memoized_attribute
def column_attrs(self):
"""Return a namespace of all :class:`.ColumnProperty`
@@ -2961,18 +2990,24 @@ class Mapper(sql_base.HasCacheKey, InspectionAttr):
(prop.key,), {"do_nothing": True}
)
- if len(self.primary_key) > 1:
- in_expr = sql.tuple_(*self.primary_key)
+ primary_key = [
+ sql_util._deep_annotate(pk, {"_orm_adapt": True})
+ for pk in self.primary_key
+ ]
+
+ if len(primary_key) > 1:
+ in_expr = sql.tuple_(*primary_key)
else:
- in_expr = self.primary_key[0]
+ in_expr = primary_key[0]
if entity.is_aliased_class:
assert entity.mapper is self
+
q = baked.BakedQuery(
self._compiled_cache,
- lambda session: session.query(entity)
- .select_entity_from(entity.selectable)
- ._adapt_all_clauses(),
+ lambda session: session.query(entity).select_entity_from(
+ entity.selectable
+ ),
(self,),
)
q.spoil()
@@ -2985,7 +3020,7 @@ class Mapper(sql_base.HasCacheKey, InspectionAttr):
q += lambda q: q.filter(
in_expr.in_(sql.bindparam("primary_keys", expanding=True))
- ).order_by(*self.primary_key)
+ ).order_by(*primary_key)
return q, enable_opt, disable_opt