summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-10-25 20:28:03 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-10-25 20:28:03 -0400
commit7f043a9666eecdecc54fe779ffdd50a7d5bb0086 (patch)
tree945a98439e89265422632d20289babbe3079f7b1 /lib/sqlalchemy/orm
parent519c705317e801d714bd05a28f8b2786695d81cc (diff)
downloadsqlalchemy-7f043a9666eecdecc54fe779ffdd50a7d5bb0086.tar.gz
- some naming changes on PropComparator, Comparator:
1. all Comparators now have "parent" which is always the parent mapper or AliasedClass instance 2. only RelationshipProperty.Comparator has "mapper" now, which is the target mapper 3. The names "parententity" and "parentmapper" are underscored also improved the message with the "neither comparator nor instruentedattribute...." to include the classname + attribute name
Diffstat (limited to 'lib/sqlalchemy/orm')
-rw-r--r--lib/sqlalchemy/orm/attributes.py19
-rw-r--r--lib/sqlalchemy/orm/interfaces.py13
-rw-r--r--lib/sqlalchemy/orm/properties.py37
-rw-r--r--lib/sqlalchemy/orm/query.py5
-rw-r--r--lib/sqlalchemy/orm/util.py2
5 files changed, 55 insertions, 21 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py
index 86da9a61d..7effd8e58 100644
--- a/lib/sqlalchemy/orm/attributes.py
+++ b/lib/sqlalchemy/orm/attributes.py
@@ -131,7 +131,7 @@ class QueryableAttribute(interfaces._MappedAttribute,
self.key = key
self.impl = impl
self.comparator = comparator
- self.parententity = parententity
+ self._parententity = parententity
self._of_type = of_type
manager = manager_of_class(class_)
@@ -159,6 +159,10 @@ class QueryableAttribute(interfaces._MappedAttribute,
return self
@property
+ def parent(self):
+ return self._parententity
+
+ @property
def expression(self):
return self.comparator.__clause_element__()
@@ -171,7 +175,7 @@ class QueryableAttribute(interfaces._MappedAttribute,
self.key,
self.impl,
self.comparator.of_type(cls),
- self.parententity,
+ self._parententity,
of_type=cls)
def label(self, name):
@@ -191,9 +195,11 @@ class QueryableAttribute(interfaces._MappedAttribute,
return getattr(self.comparator, key)
except AttributeError:
raise AttributeError(
- 'Neither %r object nor %r object has an attribute %r' % (
+ 'Neither %r object nor %r object associated with %s '
+ 'has an attribute %r' % (
type(self).__name__,
type(self.comparator).__name__,
+ self,
key)
)
@@ -281,7 +287,7 @@ def create_proxied_attribute(descriptor):
return self.descriptor.__get__(instance, owner)
def __str__(self):
- return self.key
+ return "%s.%s" % (self.class_.__name__, self.key)
def __getattr__(self, attribute):
"""Delegate __getattr__ to the original descriptor and/or
@@ -294,12 +300,15 @@ def create_proxied_attribute(descriptor):
return getattr(self.comparator, attribute)
except AttributeError:
raise AttributeError(
- 'Neither %r object nor %r object has an attribute %r' % (
+ 'Neither %r object nor %r object associated with %s '
+ 'has an attribute %r' % (
type(descriptor).__name__,
type(self.comparator).__name__,
+ self,
attribute)
)
+
Proxy.__name__ = type(descriptor).__name__ + 'Proxy'
util.monkeypatch_proxied_specials(Proxy, type(descriptor),
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index 272d4edd5..b30630434 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -305,11 +305,12 @@ class PropComparator(operators.ColumnOperators):
"""
- def __init__(self, prop, mapper, adapter=None):
+ def __init__(self, prop, parentmapper, adapter=None):
self.prop = self.property = prop
- self.mapper = mapper
+ self._parentmapper = parentmapper
self.adapter = adapter
+
def __clause_element__(self):
raise NotImplementedError("%r" % self)
@@ -319,7 +320,7 @@ class PropComparator(operators.ColumnOperators):
"""
- return self.__class__(self.prop, self.mapper, adapter)
+ return self.__class__(self.prop, self._parentmapper, adapter)
@staticmethod
def any_op(a, b, **kwargs):
@@ -503,7 +504,7 @@ class PropertyOption(MapperOption):
d['key'] = ret = []
for token in util.to_list(self.key):
if isinstance(token, PropComparator):
- ret.append((token.mapper.class_, token.key))
+ ret.append((token._parentmapper.class_, token.key))
else:
ret.append(token)
return d
@@ -628,7 +629,7 @@ class PropertyOption(MapperOption):
# matching tokens to entities
if current_path:
if current_path[0:2] == \
- [token.parententity, prop.key]:
+ [token._parententity, prop.key]:
current_path = current_path[2:]
continue
else:
@@ -638,7 +639,7 @@ class PropertyOption(MapperOption):
entity = self._find_entity_prop_comparator(
query,
prop.key,
- token.parententity,
+ token._parententity,
raiseerr)
if not entity:
return no_result
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 048b4fad3..a0abb2743 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -189,8 +189,8 @@ class ColumnProperty(StrategizedProperty):
return self.adapter(self.prop.columns[0])
else:
return self.prop.columns[0]._annotate({
- "parententity": self.mapper,
- "parentmapper": self.mapper})
+ "parententity": self._parentmapper,
+ "parentmapper": self._parentmapper})
def __getattr__(self, key):
"""proxy attribute access down to the mapped column.
@@ -352,13 +352,13 @@ class RelationshipProperty(StrategizedProperty):
_of_type = None
- def __init__(self, prop, mapper, of_type=None, adapter=None):
+ def __init__(self, prop, parentmapper, of_type=None, adapter=None):
"""Construction of :class:`.RelationshipProperty.Comparator`
is internal to the ORM's attribute mechanics.
"""
self.prop = prop
- self.mapper = mapper
+ self._parentmapper = parentmapper
self.adapter = adapter
if of_type:
self._of_type = of_type
@@ -370,14 +370,37 @@ class RelationshipProperty(StrategizedProperty):
"""
- return self.__class__(self.property, self.mapper,
+ return self.__class__(self.property, self._parentmapper,
getattr(self, '_of_type', None),
adapter)
@util.memoized_property
- def parententity(self):
+ def mapper(self):
+ """The target :class:`.Mapper` referred to by this
+ :class:`.RelationshipProperty.Comparator.
+
+ This is the "target" or "remote" side of the
+ :func:`.relationship`.
+
+ """
+ return self.property.mapper
+
+ @util.memoized_property
+ def parent(self):
+ """The parent :class:`.Mapper` or :class:`.AliasedClass`
+ referred to by this
+ :class:`.RelationshipProperty.Comparator.
+
+ This is the "parent" or "local" side of the
+ :func:`.relationship`.
+
+ """
return self.property.parent
+ @util.memoized_property
+ def _parententity(self):
+ return self.parent
+
def _source_selectable(self):
elem = self.property.parent._with_polymorphic_selectable
if self.adapter:
@@ -412,7 +435,7 @@ class RelationshipProperty(StrategizedProperty):
"""
return RelationshipProperty.Comparator(
self.property,
- self.mapper,
+ self._parentmapper,
cls, adapter=self.adapter)
def in_(self, other):
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index a6d20a973..02fb7d4f7 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -1727,7 +1727,7 @@ class Query(object):
# and Class is that of the current joinpoint
elif from_joinpoint and \
isinstance(onclause, interfaces.PropComparator):
- left_entity = onclause.parententity
+ left_entity = onclause._parententity
info = inspect(self._joinpoint_zero())
left_mapper, left_selectable, left_is_aliased = \
@@ -1750,7 +1750,8 @@ class Query(object):
else:
right_entity = onclause.property.mapper
- left_entity = onclause.parententity
+ left_entity = onclause._parententity
+ assert left_entity is onclause.parent
prop = onclause.property
if not isinstance(onclause, attributes.QueryableAttribute):
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index 2e38e0ce3..fb4197c58 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -464,7 +464,7 @@ class AliasedClass(object):
# used to assign a name to the RowTuple object
# returned by Query.
self._sa_label_name = aliased_insp.name
- self.__name__ = 'AliasedClass_' + str(self.__target)
+ self.__name__ = 'AliasedClass_%s' % self.__target.__name__
@util.memoized_property
def _sa_path_registry(self):