summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-11-10 20:22:18 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-11-10 20:22:18 +0000
commitea12a628e46783e255f5ae6068a24f29fe784d05 (patch)
tree3e34c33f7c2d85ffd97b99a1a16173f8527a3741
parenteaa359f177ac79e66142b929efb928074d9f3da0 (diff)
downloadsqlalchemy-ea12a628e46783e255f5ae6068a24f29fe784d05.tar.gz
- converted some more attributes to @memoized_property in expressions
- flattened an unnecessary KeyError in identity.py - memoized the default list of mapper properties queried in MapperEntity.setup_context
-rw-r--r--lib/sqlalchemy/orm/identity.py17
-rw-r--r--lib/sqlalchemy/orm/mapper.py15
-rw-r--r--lib/sqlalchemy/sql/expression.py61
3 files changed, 50 insertions, 43 deletions
diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py
index 8ad2b64bb..7d3856a17 100644
--- a/lib/sqlalchemy/orm/identity.py
+++ b/lib/sqlalchemy/orm/identity.py
@@ -87,10 +87,13 @@ class WeakInstanceDict(IdentityMap):
def __contains__(self, key):
try:
- state = dict.__getitem__(self, key)
- o = state.obj()
- if o is None:
- o = state._is_really_none()
+ if dict.__contains__(self, key):
+ state = dict.__getitem__(self, key)
+ o = state.obj()
+ if o is None:
+ o = state._is_really_none()
+ else:
+ return False
except KeyError:
return False
return o is not None
@@ -112,9 +115,8 @@ class WeakInstanceDict(IdentityMap):
self.remove(state)
def remove(self, state):
- if not self.contains_state(state):
+ if dict.pop(self, state.key) is not state:
raise AssertionError("State %s is not present in this identity map" % state)
- dict.__delitem__(self, state.key)
del state._instance_dict
self._manage_removed_state(state)
@@ -166,9 +168,8 @@ class StrongInstanceDict(IdentityMap):
self._manage_incoming_state(state)
def remove(self, state):
- if not self.contains_state(state):
+ if dict.pop(self, state.key) is not state:
raise AssertionError("State %s is not present in this identity map" % state)
- dict.__delitem__(self, state.key)
self._manage_removed_state(state)
def discard(self, state):
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 42597cda1..37a431012 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -857,12 +857,19 @@ class Mapper(object):
else:
return mappers, self._selectable_from_mappers(mappers)
+ @util.memoized_property
+ def _default_polymorphic_properties(self):
+ return util.unique_list(
+ chain(*[list(mapper.iterate_properties) for mapper in [self] + self._with_polymorphic_mappers])
+ )
+
def _iterate_polymorphic_properties(self, mappers=None):
if mappers is None:
- mappers = self._with_polymorphic_mappers
- return iter(util.unique_list(
- chain(*[list(mapper.iterate_properties) for mapper in [self] + mappers])
- ))
+ return iter(self._default_polymorphic_properties)
+ else:
+ return iter(util.unique_list(
+ chain(*[list(mapper.iterate_properties) for mapper in [self] + mappers])
+ ))
@property
def properties(self):
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 7ca3d7b9e..4891b5ca5 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -1844,34 +1844,36 @@ class FromClause(Selectable):
return getattr(self, 'name', self.__class__.__name__ + " object")
def _reset_exported(self):
- # delete all the "generated" collections of columns for a
- # newly cloned FromClause, so that they will be re-derived
- # from the item. this is because FromClause subclasses, when
- # cloned, need to reestablish new "proxied" columns that are
- # linked to the new item
- for attr in ('_columns', '_primary_key' '_foreign_keys', '_embedded_columns', '_all_froms'):
- if hasattr(self, attr):
- delattr(self, attr)
-
- def _expr_attr_func(name):
- get = attrgetter(name)
- def attr(self):
- try:
- return get(self)
- except AttributeError:
- self._export_columns()
- return get(self)
- return property(attr)
+ """delete memoized collections when a FromClause is cloned."""
+
+ for attr in ('_columns', '_primary_key' '_foreign_keys', 'locate_all_froms'):
+ self.__dict__.pop(attr, None)
+
+ @util.memoized_property
+ def _columns(self):
+ self._export_columns()
+ return self._columns
+
+ @util.memoized_property
+ def _primary_key(self):
+ self._export_columns()
+ return self._primary_key
- columns = c = _select_iterable = _expr_attr_func('_columns')
- primary_key = _expr_attr_func('_primary_key')
- foreign_keys = _expr_attr_func('_foreign_keys')
+ @util.memoized_property
+ def _foreign_keys(self):
+ self._export_columns()
+ return self._foreign_keys
+
+ columns = property(attrgetter('_columns'))
+ primary_key = property(attrgetter('_primary_key'))
+ foreign_keys = property(attrgetter('_foreign_keys'))
+ # synonyms for 'columns'
+ c = _select_iterable = property(attrgetter('columns'))
+
def _export_columns(self):
"""Initialize column collections."""
- if hasattr(self, '_columns'):
- return
self._columns = ColumnCollection()
self._primary_key = ColumnSet()
self._foreign_keys = set()
@@ -2622,7 +2624,6 @@ class _FromGrouping(FromClause):
@property
def columns(self):
return self.element.columns
- c = columns
@property
def _hide_froms(self):
@@ -3000,8 +3001,8 @@ class _ScalarSelect(_Grouping):
def columns(self):
raise exc.InvalidRequestError("Scalar Select expression has no columns; "
"use this object directly within a column-level expression.")
- c = columns
-
+ c = columns
+
def self_group(self, **kwargs):
return self
@@ -3169,7 +3170,8 @@ class Select(_SelectBaseMixin, FromClause):
raise exc.InvalidRequestError("Select objects don't have a type. "
"Call as_scalar() on this Select object "
"to return a 'scalar' version of this Select.")
-
+
+ @util.memoized_instancemethod
def locate_all_froms(self):
"""return a Set of all FromClause elements referenced by this Select.
@@ -3177,10 +3179,7 @@ class Select(_SelectBaseMixin, FromClause):
is specifically for those FromClause elements that would actually be rendered.
"""
- if not hasattr(self, '_all_froms'):
- self._all_froms = self._froms.union(_from_objects(*list(self._froms)))
-
- return self._all_froms
+ return self._froms.union(_from_objects(*list(self._froms)))
@property
def inner_columns(self):