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.py80
1 files changed, 54 insertions, 26 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 337a7178b..2d3bceb92 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -80,6 +80,7 @@ from ..sql import roles
from ..sql import util as sql_util
from ..sql import visitors
from ..sql.cache_key import MemoizedHasCacheKey
+from ..sql.elements import KeyedColumnElement
from ..sql.schema import Table
from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
from ..util import HasMemoized
@@ -108,7 +109,6 @@ if TYPE_CHECKING:
from ..sql.base import ReadOnlyColumnCollection
from ..sql.elements import ColumnClause
from ..sql.elements import ColumnElement
- from ..sql.elements import KeyedColumnElement
from ..sql.schema import Column
from ..sql.selectable import FromClause
from ..sql.util import ColumnAdapter
@@ -182,6 +182,7 @@ class Mapper(
dispatch: dispatcher[Mapper[_O]]
_dispose_called = False
+ _configure_failed: Any = False
_ready_for_configure = False
@util.deprecated_params(
@@ -710,8 +711,11 @@ class Mapper(
self.batch = batch
self.eager_defaults = eager_defaults
self.column_prefix = column_prefix
- self.polymorphic_on = (
- coercions.expect(
+
+ # interim - polymorphic_on is further refined in
+ # _configure_polymorphic_setter
+ self.polymorphic_on = ( # type: ignore
+ coercions.expect( # type: ignore
roles.ColumnArgumentOrKeyRole,
polymorphic_on,
argname="polymorphic_on",
@@ -1832,12 +1836,22 @@ class Mapper(
)
@util.preload_module("sqlalchemy.orm.descriptor_props")
- def _configure_property(self, key, prop, init=True, setparent=True):
+ def _configure_property(
+ self,
+ key: str,
+ prop_arg: Union[KeyedColumnElement[Any], MapperProperty[Any]],
+ init: bool = True,
+ setparent: bool = True,
+ ) -> MapperProperty[Any]:
descriptor_props = util.preloaded.orm_descriptor_props
- self._log("_configure_property(%s, %s)", key, prop.__class__.__name__)
+ self._log(
+ "_configure_property(%s, %s)", key, prop_arg.__class__.__name__
+ )
- if not isinstance(prop, MapperProperty):
- prop = self._property_from_column(key, prop)
+ if not isinstance(prop_arg, MapperProperty):
+ prop = self._property_from_column(key, prop_arg)
+ else:
+ prop = prop_arg
if isinstance(prop, properties.ColumnProperty):
col = self.persist_selectable.corresponding_column(prop.columns[0])
@@ -1950,18 +1964,23 @@ class Mapper(
if self.configured:
self._expire_memoizations()
+ return prop
+
@util.preload_module("sqlalchemy.orm.descriptor_props")
- def _property_from_column(self, key, prop):
+ def _property_from_column(
+ self,
+ key: str,
+ prop_arg: Union[KeyedColumnElement[Any], MapperProperty[Any]],
+ ) -> MapperProperty[Any]:
"""generate/update a :class:`.ColumnProperty` given a
:class:`_schema.Column` object."""
descriptor_props = util.preloaded.orm_descriptor_props
# we were passed a Column or a list of Columns;
# generate a properties.ColumnProperty
- columns = util.to_list(prop)
+ columns = util.to_list(prop_arg)
column = columns[0]
- assert isinstance(column, expression.ColumnElement)
- prop = self._props.get(key, None)
+ prop = self._props.get(key)
if isinstance(prop, properties.ColumnProperty):
if (
@@ -2033,11 +2052,11 @@ class Mapper(
"columns get mapped." % (key, self, column.key, prop)
)
- def _check_configure(self):
+ def _check_configure(self) -> None:
if self.registry._new_mappers:
_configure_registries({self.registry}, cascade=True)
- def _post_configure_properties(self):
+ def _post_configure_properties(self) -> None:
"""Call the ``init()`` method on all ``MapperProperties``
attached to this mapper.
@@ -2068,7 +2087,9 @@ class Mapper(
for key, value in dict_of_properties.items():
self.add_property(key, value)
- def add_property(self, key, prop):
+ def add_property(
+ self, key: str, prop: Union[Column[Any], MapperProperty[Any]]
+ ) -> None:
"""Add an individual MapperProperty to this mapper.
If the mapper has not been configured yet, just adds the
@@ -2077,15 +2098,16 @@ class Mapper(
the given MapperProperty is configured immediately.
"""
+ prop = self._configure_property(key, prop, init=self.configured)
+ assert isinstance(prop, MapperProperty)
self._init_properties[key] = prop
- self._configure_property(key, prop, init=self.configured)
- def _expire_memoizations(self):
+ def _expire_memoizations(self) -> None:
for mapper in self.iterate_to_root():
mapper._reset_memoizations()
@property
- def _log_desc(self):
+ def _log_desc(self) -> str:
return (
"("
+ self.class_.__name__
@@ -2099,16 +2121,16 @@ class Mapper(
+ ")"
)
- def _log(self, msg, *args):
+ def _log(self, msg: str, *args: Any) -> None:
self.logger.info("%s " + msg, *((self._log_desc,) + args))
- def _log_debug(self, msg, *args):
+ def _log_debug(self, msg: str, *args: Any) -> None:
self.logger.debug("%s " + msg, *((self._log_desc,) + args))
- def __repr__(self):
+ def __repr__(self) -> str:
return "<Mapper at 0x%x; %s>" % (id(self), self.class_.__name__)
- def __str__(self):
+ def __str__(self) -> str:
return "Mapper[%s%s(%s)]" % (
self.class_.__name__,
self.non_primary and " (non-primary)" or "",
@@ -2155,7 +2177,9 @@ class Mapper(
"Mapper '%s' has no property '%s'" % (self, key)
) from err
- def get_property_by_column(self, column):
+ def get_property_by_column(
+ self, column: ColumnElement[_T]
+ ) -> MapperProperty[_T]:
"""Given a :class:`_schema.Column` object, return the
:class:`.MapperProperty` which maps this column."""
@@ -2795,7 +2819,7 @@ class Mapper(
return result
- def _is_userland_descriptor(self, assigned_name, obj):
+ def _is_userland_descriptor(self, assigned_name: str, obj: Any) -> bool:
if isinstance(
obj,
(
@@ -3603,7 +3627,9 @@ def configure_mappers():
_configure_registries(_all_registries(), cascade=True)
-def _configure_registries(registries, cascade):
+def _configure_registries(
+ registries: Set[_RegistryType], cascade: bool
+) -> None:
for reg in registries:
if reg._new_mappers:
break
@@ -3637,7 +3663,9 @@ def _configure_registries(registries, cascade):
@util.preload_module("sqlalchemy.orm.decl_api")
-def _do_configure_registries(registries, cascade):
+def _do_configure_registries(
+ registries: Set[_RegistryType], cascade: bool
+) -> None:
registry = util.preloaded.orm_decl_api.registry
@@ -3688,7 +3716,7 @@ def _do_configure_registries(registries, cascade):
@util.preload_module("sqlalchemy.orm.decl_api")
-def _dispose_registries(registries, cascade):
+def _dispose_registries(registries: Set[_RegistryType], cascade: bool) -> None:
registry = util.preloaded.orm_decl_api.registry