summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm')
-rw-r--r--lib/sqlalchemy/orm/dynamic.py2
-rw-r--r--lib/sqlalchemy/orm/interfaces.py6
-rw-r--r--lib/sqlalchemy/orm/mapper.py30
-rw-r--r--lib/sqlalchemy/orm/properties.py16
-rw-r--r--lib/sqlalchemy/orm/query.py2
-rw-r--r--lib/sqlalchemy/orm/scoping.py3
-rw-r--r--lib/sqlalchemy/orm/strategies.py4
-rw-r--r--lib/sqlalchemy/orm/util.py11
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