summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/interfaces.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-01-05 19:02:08 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2015-01-05 19:02:08 -0500
commit1104dcaa67062f27bf7519c8589f550bd5d5b4af (patch)
tree702802bd3f0e5db235a109ba48707ea262f1782b /lib/sqlalchemy/orm/interfaces.py
parent41ae0270d99793608ce563b84e7befb3aa39252e (diff)
downloadsqlalchemy-1104dcaa67062f27bf7519c8589f550bd5d5b4af.tar.gz
- add MemoizedSlots, a generalized solution to using __getattr__
for memoization on a class that uses slots. - apply many more __slots__. mem use for nova now at 46% savings
Diffstat (limited to 'lib/sqlalchemy/orm/interfaces.py')
-rw-r--r--lib/sqlalchemy/orm/interfaces.py51
1 files changed, 43 insertions, 8 deletions
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index 68b86268c..346e2412e 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -24,7 +24,8 @@ from .. import util
from ..sql import operators
from .base import (ONETOMANY, MANYTOONE, MANYTOMANY,
EXT_CONTINUE, EXT_STOP, NOT_EXTENSION)
-from .base import InspectionAttr, _MappedAttribute
+from .base import (InspectionAttr, InspectionAttr,
+ InspectionAttrInfo, _MappedAttribute)
import collections
# imported later
@@ -48,7 +49,7 @@ __all__ = (
)
-class MapperProperty(_MappedAttribute, InspectionAttr):
+class MapperProperty(_MappedAttribute, InspectionAttr, util.MemoizedSlots):
"""Manage the relationship of a ``Mapper`` to a single class
attribute, as well as that attribute as it appears on individual
instances of the class, including attribute instrumentation,
@@ -63,6 +64,11 @@ class MapperProperty(_MappedAttribute, InspectionAttr):
"""
+ __slots__ = (
+ '_configure_started', '_configure_finished', 'parent', 'key',
+ 'info'
+ )
+
cascade = frozenset()
"""The set of 'cascade' attribute names.
@@ -78,6 +84,32 @@ class MapperProperty(_MappedAttribute, InspectionAttr):
"""
+ def _memoized_attr_info(self):
+ """Info dictionary associated with the object, allowing user-defined
+ data to be associated with this :class:`.InspectionAttr`.
+
+ The dictionary is generated when first accessed. Alternatively,
+ it can be specified as a constructor argument to the
+ :func:`.column_property`, :func:`.relationship`, or :func:`.composite`
+ functions.
+
+ .. versionadded:: 0.8 Added support for .info to all
+ :class:`.MapperProperty` subclasses.
+
+ .. versionchanged:: 1.0.0 :attr:`.InspectionAttr.info` moved
+ from :class:`.MapperProperty` so that it can apply to a wider
+ variety of ORM and extension constructs.
+
+ .. seealso::
+
+ :attr:`.QueryableAttribute.info`
+
+ :attr:`.SchemaItem.info`
+
+ """
+ return {}
+
+
def setup(self, context, entity, path, adapter, **kwargs):
"""Called by Query for the purposes of constructing a SQL statement.
@@ -139,8 +171,9 @@ class MapperProperty(_MappedAttribute, InspectionAttr):
"""
- _configure_started = False
- _configure_finished = False
+ def __init__(self):
+ self._configure_started = False
+ self._configure_finished = False
def init(self):
"""Called after all mappers are created to assemble
@@ -422,6 +455,8 @@ class StrategizedProperty(MapperProperty):
"""
+ __slots__ = '_strategies', 'strategy'
+
strategy_wildcard_key = None
def _get_context_loader(self, context, path):
@@ -485,14 +520,14 @@ class StrategizedProperty(MapperProperty):
not mapper.class_manager._attr_has_impl(self.key):
self.strategy.init_class_attribute(mapper)
- _strategies = collections.defaultdict(dict)
+ _all_strategies = collections.defaultdict(dict)
@classmethod
def strategy_for(cls, **kw):
def decorate(dec_cls):
dec_cls._strategy_keys = []
key = tuple(sorted(kw.items()))
- cls._strategies[cls][key] = dec_cls
+ cls._all_strategies[cls][key] = dec_cls
dec_cls._strategy_keys.append(key)
return dec_cls
return decorate
@@ -500,8 +535,8 @@ class StrategizedProperty(MapperProperty):
@classmethod
def _strategy_lookup(cls, *key):
for prop_cls in cls.__mro__:
- if prop_cls in cls._strategies:
- strategies = cls._strategies[prop_cls]
+ if prop_cls in cls._all_strategies:
+ strategies = cls._all_strategies[prop_cls]
try:
return strategies[key]
except KeyError: