wouldn't be deserialized correctly when the whole object
was serialized. [ticket:1426]
+ - Fixed Query being able to join() from individual columns of
+ a joined-table subclass entity, i.e.
+ query(SubClass.foo, SubcClass.bar).join(<anything>).
+ In most cases, an error "Could not find a FROM clause to join
+ from" would be raised. In a few others, the result would be
+ returned in terms of the base class rather than the subclass -
+ so applications which relied on this erroneous result need to be
+ adjusted. [ticket:1431]
+
- sql
- Removed an obscure feature of execute() (including connection,
engine, Session) whereby a bindparam() construct can be sent as
# after the method completes,
# the query's joinpoint will be set to this.
right_entity = None
-
+
for arg1 in util.to_list(keys):
aliased_entity = False
alias_criterion = False
clause = ent.selectable
break
+ # TODO:
+ # this provides one kind of "backwards join"
+ # tested in test/orm/query.py.
+ # remove this in 0.6
if not clause:
if isinstance(onclause, interfaces.PropComparator):
clause = onclause.__clause_element__()
if _is_aliased_class(entity):
return entity is self.entity_zero
else:
- # TODO: this will fail with inheritance, entity_zero
- # is not a base mapper. MapperEntity has path_entity
- # which serves this purpose (when saying: query(FooBar.somecol).join(SomeClass, FooBar.id==SomeClass.foo_id))
- return entity.base_mapper is self.entity_zero
-
+ return not _is_aliased_class(self.entity_zero) and entity.base_mapper.common_parent(self.entity_zero)
+
def _resolve_expr_against_query_aliases(self, query, expr, context):
return query._adapt_clause(expr, False, True)
c2
)
-
+ def test_join_from_columns_or_subclass(self):
+ sess = create_session()
+
+ self.assertEquals(
+ sess.query(Manager.name).order_by(Manager.name).all(),
+ [(u'dogbert',), (u'pointy haired boss',)]
+ )
+
+ self.assertEquals(
+ sess.query(Manager.name).join((Paperwork, Manager.paperwork)).order_by(Manager.name).all(),
+ [(u'dogbert',), (u'dogbert',), (u'pointy haired boss',)]
+ )
+
+ self.assertEquals(
+ sess.query(Person.name).join((Paperwork, Person.paperwork)).order_by(Person.name).all(),
+ [(u'dilbert',), (u'dilbert',), (u'dogbert',), (u'dogbert',), (u'pointy haired boss',), (u'vlad',), (u'wally',), (u'wally',)]
+ )
+
+ self.assertEquals(
+ sess.query(Person.name).join((paperwork, Manager.person_id==paperwork.c.person_id)).order_by(Person.name).all(),
+ [(u'dilbert',), (u'dilbert',), (u'dogbert',), (u'dogbert',), (u'pointy haired boss',), (u'vlad',), (u'wally',), (u'wally',)]
+ )
+
+ self.assertEquals(
+ sess.query(Manager).join((Paperwork, Manager.paperwork)).order_by(Manager.name).all(),
+ [m1, b1]
+ )
+
+ self.assertEquals(
+ sess.query(Manager.name).join((paperwork, Manager.person_id==paperwork.c.person_id)).order_by(Manager.name).all(),
+ [(u'dogbert',), (u'dogbert',), (u'pointy haired boss',)]
+ )
+
+ self.assertEquals(
+ sess.query(Manager.person_id).join((paperwork, Manager.person_id==paperwork.c.person_id)).order_by(Manager.name).all(),
+ [(4,), (4,), (3,)]
+ )
+
+ self.assertEquals(
+ sess.query(Manager.name, Paperwork.description).join((Paperwork, Manager.person_id==Paperwork.person_id)).all(),
+ [(u'pointy haired boss', u'review #1'), (u'dogbert', u'review #2'), (u'dogbert', u'review #3')]
+ )
+
+ malias = aliased(Manager)
+ self.assertEquals(
+ sess.query(malias.name).join((paperwork, malias.person_id==paperwork.c.person_id)).all(),
+ [(u'pointy haired boss',), (u'dogbert',), (u'dogbert',)]
+ )
+
def test_expire(self):
"""test that individual column refresh doesn't get tripped up by the select_table mapper"""
]
)
+ def test_plain_table(self):
+
+ sess = create_session()
+
+ self.assertEquals(
+ sess.query(User.name).join((addresses, User.id==addresses.c.user_id)).order_by(User.id).all(),
+ [(u'jack',), (u'ed',), (u'ed',), (u'ed',), (u'fred',)]
+ )
+
+
class MultiplePathTest(_base.MappedTest):
def define_tables(self, metadata):
global t1, t2, t1t2_1, t1t2_2