Re: [Sqlalchemy-tickets] [sqlalchemy] #2908: Regression in 0.9.x for polymorphic query
Brought to you by:
zzzeek
|
From: sqlalchemy <mi...@zz...> - 2014-01-13 06:49:19
|
#2908: Regression in 0.9.x for polymorphic query
---------------------------------+-------------------------------
Reporter: jeremy.skippen | Owner: zzzeek
Type: defect | Status: new
Priority: highest | Milestone: 0.9.xx
Component: orm | Severity: major - 1-3 hours
Resolution: | Keywords:
Progress State: in progress |
---------------------------------+-------------------------------
Changes (by zzzeek):
* priority: medium => highest
* severity: no triage selected yet => major - 1-3 hours
* status_field: awaiting triage => in progress
Comment:
(internal pdb notes follow)
the turning point that is different in 0.9 is due to clause adaptation
failing for raw joins, branch point is in orm/util.py, when joining for
joinedload for second User.profile:
{{{
if prop:
if sql_util.clause_is_present(on_selectable,
left_info.selectable):
adapt_from = on_selectable
else:
adapt_from = left_info.selectable
}}}
the clause_is_present() check fails and it the join doesn't have a
specific enough "adapt_from".
that check fails because onclause.comparator._source_selectable() does
this: the mapped entity is:
{{{
> /Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/util.py(744)__init__()
-> left_orm_info = getattr(left, '_joined_from_info', left_info)
(Pdb) print
onclause.comparator.property.parent._with_polymorphic_selectable
party JOIN "user" ON party.party_id = "user".party_id
(Pdb)
}}}
the _adapt_to_entity is:
{{{
(Pdb) print onclause.comparator._adapt_to_entity.selectable
party AS party_1 JOIN "user" AS user_1 ON party_1.party_id =
user_1.party_id
}}}
the adaptation in _source_selectable() fails, by taking the
_adapt_to_entity and replacing it for both "party" and "user" in the
mapped selectable, forming a garbage selectable:
{{{
(Pdb) print onclause.comparator._source_selectable()
party AS party_1 JOIN "user" AS user_1 ON party_1.party_id =
user_1.party_id JOIN party AS party_1 JOIN "user" AS user_1 ON
party_1.party_id = user_1.party_id ON party_1.party_id = user_1.party_id
}}}
so the issue is ultimately with _source_selectable().
so far a diff like this is working:
{{{
diff --git a/lib/sqlalchemy/orm/relationships.py
b/lib/sqlalchemy/orm/relationships.py
index 982f10a..6fdedd3 100644
--- a/lib/sqlalchemy/orm/relationships.py
+++ b/lib/sqlalchemy/orm/relationships.py
@@ -747,11 +747,10 @@ class RelationshipProperty(StrategizedProperty):
return self.property.parent
def _source_selectable(self):
- elem = self.property.parent._with_polymorphic_selectable
- if self.adapter:
- return self.adapter(elem)
+ if self._adapt_to_entity:
+ return self._adapt_to_entity.selectable
else:
- return elem
+ return self.property.parent._with_polymorphic_selectable
def __clause_element__(self):
adapt_from = self._source_selectable()
}}}
but we can't test it fully because #2907 is breaking all the tests, so
have to fix that first.
--
Ticket URL: <http://www.sqlalchemy.org/trac/ticket/2908#comment:1>
sqlalchemy <http://www.sqlalchemy.org/>
The Database Toolkit for Python
|