diff options
Diffstat (limited to 'lib/sqlalchemy/orm')
| -rw-r--r-- | lib/sqlalchemy/orm/dynamic.py | 2 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 30 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/properties.py | 16 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/query.py | 2 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/scoping.py | 3 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 4 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/util.py | 11 |
8 files changed, 34 insertions, 40 deletions
diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py index d55838011..d2063dbc6 100644 --- a/lib/sqlalchemy/orm/dynamic.py +++ b/lib/sqlalchemy/orm/dynamic.py @@ -192,7 +192,7 @@ class AppenderMixin(object): self.attr = attr mapper = object_mapper(instance) - prop = mapper.get_property(self.attr.key, resolve_synonyms=True) + prop = mapper.get_property(self.attr.key) self._criterion = prop.compare( operators.eq, instance, diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 91c2ae403..405316976 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -838,8 +838,10 @@ class PropertyOption(MapperOption): path_element = entity.path_entity mapper = entity.mapper mappers.append(mapper) - prop = mapper.get_property(token, - resolve_synonyms=True, raiseerr=raiseerr) + if mapper.has_property(token): + prop = mapper.get_property(token) + else: + prop = None key = token elif isinstance(token, PropComparator): prop = token.property diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 9cb358151..7c2f550eb 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -905,26 +905,22 @@ class Mapper(object): def has_property(self, key): return key in self._props - def get_property(self, key, resolve_synonyms=False, raiseerr=True): - """return a MapperProperty associated with the given key.""" + def get_property(self, key, _compile_mappers=True): + """return a MapperProperty associated with the given key. + + Calls getattr() against the mapped class itself, so that class-level + proxies will be resolved to the underlying property, if any. + + """ - if not self.compiled: + if _compile_mappers and not self.compiled: self.compile() - return self._get_property(key, - resolve_synonyms=resolve_synonyms, - raiseerr=raiseerr) - - def _get_property(self, key, resolve_synonyms=False, raiseerr=True): - prop = self._props.get(key, None) - if resolve_synonyms: - while isinstance(prop, SynonymProperty): - prop = self._props.get(prop.name, None) - if prop is None and raiseerr: + try: + return getattr(self.class_, key).property + except AttributeError: raise sa_exc.InvalidRequestError( - "Mapper '%s' has no property '%s'" % - (self, key)) - return prop - + "Mapper '%s' has no property '%s'" % (self, key)) + @property def iterate_properties(self): """return an iterator of all MapperProperty objects.""" diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index cf5f31162..53503862b 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -284,7 +284,7 @@ class ConcreteInheritedProperty(MapperProperty): comparator_callable = None # TODO: put this process into a deferred callable? for m in self.parent.iterate_to_root(): - p = m._get_property(self.key) + p = m._props[self.key] if not isinstance(p, ConcreteInheritedProperty): comparator_callable = p.comparator_factory break @@ -337,8 +337,8 @@ class SynonymProperty(MapperProperty): def comparator_callable(prop, mapper): def comparator(): - prop = self.parent._get_property( - self.key, resolve_synonyms=True) + prop = getattr(self.parent.class_, + self.name).property if self.comparator_factory: return self.comparator_factory(prop, mapper) else: @@ -837,7 +837,7 @@ class RelationshipProperty(StrategizedProperty): yield (c, instance_mapper, instance_state) def _add_reverse_property(self, key): - other = self.mapper._get_property(key) + other = self.mapper.get_property(key, _compile_mappers=False) self._reverse_property.add(other) other._reverse_property.add(self) @@ -924,8 +924,7 @@ class RelationshipProperty(StrategizedProperty): if not self.parent.concrete: for inheriting in self.parent.iterate_to_root(): if inheriting is not self.parent \ - and inheriting._get_property(self.key, - raiseerr=False): + and inheriting.has_property(self.key): util.warn("Warning: relationship '%s' on mapper " "'%s' supercedes the same relationship " "on inherited mapper '%s'; this can " @@ -1216,7 +1215,7 @@ class RelationshipProperty(StrategizedProperty): def _assert_is_primary(self): if not self.is_primary() \ and not mapper.class_mapper(self.parent.class_, - compile=False)._get_property(self.key, raiseerr=False): + compile=False).has_property(self.key): raise sa_exc.ArgumentError("Attempting to assign a new " "relationship '%s' to a non-primary mapper on " "class '%s'. New relationships can only be added " @@ -1234,8 +1233,7 @@ class RelationshipProperty(StrategizedProperty): else: backref_key, kwargs = self.backref mapper = self.mapper.primary_mapper() - if mapper._get_property(backref_key, raiseerr=False) \ - is not None: + if mapper.has_property(backref_key): raise sa_exc.ArgumentError("Error creating backref " "'%s' on relationship '%s': property of that " "name exists on mapper '%s'" % (backref_key, diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index cc6d15a74..8d468babe 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -662,7 +662,7 @@ class Query(object): instance.__class__.__name__) ) else: - prop = mapper.get_property(property, resolve_synonyms=True) + prop = mapper.get_property(property) return self.filter(prop.compare( operators.eq, instance, value_is_parent=True)) diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py index 40bbb3299..1b9ad8e6f 100644 --- a/lib/sqlalchemy/orm/scoping.py +++ b/lib/sqlalchemy/orm/scoping.py @@ -179,8 +179,7 @@ class _ScopedExt(MapperExtension): def __init__(self, **kwargs): for key, value in kwargs.iteritems(): if ext.validate: - if not mapper.get_property(key, resolve_synonyms=False, - raiseerr=False): + if not mapper.has_property(key): raise sa_exc.ArgumentError( "Invalid __init__ argument: '%s'" % key) setattr(self, key, value) diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 1c4571aed..afa3ebf4c 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -1215,7 +1215,7 @@ class LoadEagerFromAliasOption(PropertyOption): if isinstance(self.alias, basestring): mapper = mappers[-1] (root_mapper, propname) = paths[-1][-2:] - prop = mapper.get_property(propname, resolve_synonyms=True) + prop = mapper.get_property(propname) self.alias = prop.target.alias(self.alias) query._attributes[ ("user_defined_eager_row_processor", @@ -1224,7 +1224,7 @@ class LoadEagerFromAliasOption(PropertyOption): else: (root_mapper, propname) = paths[-1][-2:] mapper = mappers[-1] - prop = mapper.get_property(propname, resolve_synonyms=True) + prop = mapper.get_property(propname) adapter = query._polymorphic_adapters.get(prop.mapper, None) query._attributes[ ("user_defined_eager_row_processor", diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index ef5413724..c9004990a 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -347,10 +347,6 @@ class AliasedClass(object): return queryattr def __getattr__(self, key): - prop = self.__mapper._get_property(key, raiseerr=False) - if prop: - return self.__adapt_prop(prop) - for base in self.__target.__mro__: try: attr = object.__getattribute__(base, key) @@ -360,7 +356,10 @@ class AliasedClass(object): break else: raise AttributeError(key) - + + if isinstance(attr, attributes.QueryableAttribute): + return self.__adapt_prop(attr.property) + if hasattr(attr, 'func_code'): is_method = getattr(self.__target, key, None) if is_method and is_method.im_self is not None: @@ -494,7 +493,7 @@ def with_parent(instance, prop): """ if isinstance(prop, basestring): mapper = object_mapper(instance) - prop = mapper.get_property(prop, resolve_synonyms=True) + prop = mapper.get_property(prop) elif isinstance(prop, attributes.QueryableAttribute): prop = prop.property |
