- marked as critical
_adjust_for_single_table_inheritance() can't be invoked if the target is an outer join
Issue #2328
resolved
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import *
from sqlalchemy.orm import *
Base = declarative_base()
class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
disc = Column(Unicode, nullable=False)
name = Column(Unicode)
__mapper_args__ = {'polymorphic_on': disc}
class B(A):
__mapper_args__ = {'polymorphic_identity': 'b'}
class Z(Base):
__tablename__ = 'z'
id = Column(Integer, primary_key=True)
b_id = Column(Integer, ForeignKey(B.id))
b = relationship(B)
session = Session()
query = session.query(Z, B.name).outerjoin(Z.b).filter(Z.id == 1)
print query
Comments (5)
-
reporter -
reporter the above patch needs to be adjusted to account for aliases. "mapper" is not specific enough.
-
reporter here's that:
diff -r 25f77454bdbfbe994eeb92a9824f135a603a0776 lib/sqlalchemy/orm/query.py --- a/lib/sqlalchemy/orm/query.py Mon Nov 14 19:24:08 2011 -0500 +++ b/lib/sqlalchemy/orm/query.py Wed Nov 16 00:11:09 2011 -0500 @@ -89,6 +89,7 @@ _only_load_props = None _refresh_state = None _from_obj = () + _join_entities = () _select_from_entity = None _filter_aliases = None _from_obj_alias = None @@ -1641,6 +1642,9 @@ left_mapper, left_selectable, left_is_aliased = _entity_info(left) right_mapper, right_selectable, right_is_aliased = _entity_info(right) + if right_mapper: + self._join_entities += (right, ) + if right_mapper and prop and \ not right_mapper.common_parent(prop.mapper): raise sa_exc.InvalidRequestError( @@ -2818,9 +2822,10 @@ selected from the total results. """ - for entity, (mapper, adapter, s, i, w) in \ self._mapper_adapter_map.iteritems(): + if entity in self._join_entities: + continue single_crit = mapper._single_table_criterion if single_crit is not None: if adapter:
some tests:
print session.query(Z, B.name).outerjoin(Z.b).filter(Z.id == 1) ba = aliased(B) print session.query(Z, ba.name).outerjoin(ba, Z.b).filter(Z.id == 1) print session.query(Z, B.name, ba.name).outerjoin(ba, Z.b).filter(Z.id == 1) print session.query(Z, B.name, ba.name).outerjoin(Z.b).filter(Z.id == 1)
-
reporter - changed status to resolved
-
reporter - removed milestone
Removing milestone: 0.7.4 (automated comment)
- Log in to comment
this patch adds a specific collection of "right mappers joined to" which is possibly a decent candidate to consider as "handled". This may change behavior if someone is joining on explicit criterion and depending on the WHERE clause, though a join to a single-inh should really be handling the discrimination in the ON clause. One option would be to limit the collection just to OUTER joins. But it is tempting to apply a fix for the redundant WHERE overall.