summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-11-24 16:14:58 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2012-11-24 16:14:58 -0500
commite2697d547ec8c24c9a37a72fc60abe73b7dee81b (patch)
tree7996ba7bb2879fc97f41526211a04a975952e4f0 /lib/sqlalchemy/orm
parent252bce8b02b1587a26b899c644ba28e78f5db4bc (diff)
downloadsqlalchemy-e2697d547ec8c24c9a37a72fc60abe73b7dee81b.tar.gz
Added a new exception to detect the case where two
subclasses are being loaded using with_polymorphic(), each subclass contains a relationship attribute of the same name, and eager loading is being applied to one or both. This is an ongoing bug which can't be immediately fixed, so since the results are usually wrong in any case it raises an exception for now. 0.7 has the same issue, so an exception raise here probably means the code was returning the wrong data in 0.7. [ticket:2614]
Diffstat (limited to 'lib/sqlalchemy/orm')
-rw-r--r--lib/sqlalchemy/orm/strategies.py19
-rw-r--r--lib/sqlalchemy/orm/util.py6
2 files changed, 23 insertions, 2 deletions
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 39329f9b1..586ec4b4e 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -303,6 +303,17 @@ class AbstractRelationshipLoader(LoaderStrategy):
self.uselist = self.parent_property.uselist
+ def _warn_existing_path(self):
+ raise sa_exc.InvalidRequestError(
+ "Eager loading cannot currently function correctly when two or "
+ "more "
+ "same-named attributes associated with multiple polymorphic "
+ "classes "
+ "of the same base are present. Encountered more than one "
+ r"eager path for attribute '%s' on mapper '%s'." %
+ (self.key, self.parent.base_mapper, ))
+
+
class NoLoader(AbstractRelationshipLoader):
"""Provide loading behavior for a :class:`.RelationshipProperty`
with "lazy=None".
@@ -746,7 +757,9 @@ class SubqueryLoader(AbstractRelationshipLoader):
# add new query to attributes to be picked up
# by create_row_processor
- path.set(context, "subquery", q)
+ existing = path.replace(context, "subquery", q)
+ if existing:
+ self._warn_existing_path()
def _get_leftmost(self, subq_path):
subq_path = subq_path.path
@@ -1091,7 +1104,9 @@ class JoinedLoader(AbstractRelationshipLoader):
)
add_to_collection = context.secondary_columns
- path.set(context, "eager_row_processor", clauses)
+ existing = path.replace(context, "eager_row_processor", clauses)
+ if existing:
+ self._warn_existing_path()
return clauses, adapter, add_to_collection, allow_innerjoin
def _create_eager_join(self, context, entity,
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index 97baffc9a..e5e725138 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -279,6 +279,12 @@ class PathRegistry(object):
def set(self, reg, key, value):
reg._attributes[(key, self.reduced_path)] = value
+ def replace(self, reg, key, value):
+ path_key = (key, self.reduced_path)
+ existing = reg._attributes.get(path_key, None)
+ reg._attributes[path_key] = value
+ return existing
+
def setdefault(self, reg, key, value):
reg._attributes.setdefault((key, self.reduced_path), value)