a tuple is inadvertently passed to session.query()
[ticket:2297]. Also in 0.6.9.
+ - [bug] Calls to query.join() to a single-table
+ inheritance subclass are now tracked, and
+ are used to eliminate the additional WHERE..
+ IN criterion normally tacked on with single
+ table inheritance, since the join should
+ accommodate it. This allows OUTER JOIN
+ to a single table subclass to produce
+ the correct results, and overall will produce
+ fewer WHERE criterion when dealing with
+ single table inheritance joins.
+ [ticket:2328]
+
- sql
- [bug] related to [ticket:2316], made some
adjustments to the change from [ticket:2261]
_only_load_props = None
_refresh_state = None
_from_obj = ()
+ _join_entities = ()
_select_from_entity = None
_filter_aliases = None
_from_obj_alias = None
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(
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:
use_default_dialect=True
)
-class RelationshipToSingleTest(fixtures.MappedTest):
+class RelationshipToSingleTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
+ __dialect__ = 'default'
+
@classmethod
def define_tables(cls, metadata):
Table('employees', metadata,
pass
def test_of_type(self):
- JuniorEngineer, Company, companies, Manager, Employee, employees, Engineer = (self.classes.JuniorEngineer,
+ JuniorEngineer, Company, companies, Manager,\
+ Employee, employees, Engineer = (self.classes.JuniorEngineer,
self.classes.Company,
self.tables.companies,
self.classes.Manager,
]
)
+ def test_outer_join(self):
+ Company, Employee, Engineer = self.classes.Company,\
+ self.classes.Employee,\
+ self.classes.Engineer
+ companies, employees = self.tables.companies, self.tables.employees
+
+ mapper(Company, companies, properties={
+ 'engineers':relationship(Engineer)
+ })
+ mapper(Employee, employees, polymorphic_on=employees.c.type)
+ mapper(Engineer, inherits=Employee, polymorphic_identity='engineer')
+
+ sess = create_session()
+ self.assert_compile(
+ sess.query(Company, Engineer.name).outerjoin("engineers"),
+ "SELECT companies.company_id AS companies_company_id, "
+ "companies.name AS companies_name, employees.name AS employees_name "
+ "FROM companies LEFT OUTER JOIN employees ON companies.company_id "
+ "= employees.company_id AND employees.type IN (:type_1)"
+ )
+
+ def test_outer_join_alias(self):
+ Company, Employee, Engineer = self.classes.Company,\
+ self.classes.Employee,\
+ self.classes.Engineer
+ companies, employees = self.tables.companies, self.tables.employees
+
+ mapper(Company, companies, properties={
+ 'engineers':relationship(Engineer)
+ })
+ mapper(Employee, employees, polymorphic_on=employees.c.type)
+ mapper(Engineer, inherits=Employee, polymorphic_identity='engineer')
+
+ eng_alias = aliased(Engineer)
+ sess = create_session()
+ self.assert_compile(
+ sess.query(Company, eng_alias.name).outerjoin(eng_alias, Company.engineers),
+ "SELECT companies.company_id AS companies_company_id, "
+ "companies.name AS companies_name, employees_1.name AS "
+ "employees_1_name FROM companies LEFT OUTER "
+ "JOIN employees AS employees_1 ON companies.company_id "
+ "= employees_1.company_id AND employees_1.type IN (:type_1)"
+ )
+
def test_relationship_to_subclass(self):
JuniorEngineer, Company, companies, Manager, Employee, employees, Engineer = (self.classes.JuniorEngineer,