On 17.9.2012 14:54, Michael Bayer wrote: > > On Sep 17, 2012, at 7:19 AM, Ladislav Lenart wrote: > >> Hello. >> >> Imagine the following ORM definition in PostgreSQL: >> >> class Node(Base): >> __tablename__ = 'node' >> id = Column(Integer(), primary_key=True) >> parent_id = Column(Integer(), ForeignKey('node.id')) >> # more data... >> >> with the following query method: >> >> def path_to_root(self, root_id=None, load_all=True): >> cls = self.__class__ >> q_base = session.query(cls).filter(cls.id == self.id) >> q_cte = q_base.cte(name='q_cte', recursive=True) >> q_cte_alias = aliased(q_cte, name='q_cte_alias') >> cls_alias = aliased(cls, name='cls_alias') >> q_rec = session.query(cls_alias) >> q_rec = q_rec.filter(cls_alias.id == q_cte_alias.c.parent_id) >> q_rec = q_rec.filter(cls_alias.id != root_id) >> q_cte_union = q_cte.union_all(q_rec) >> q = session.query(cls).select_from(q_cte_union) >> q = q.options(joinedload_all(cls.foo, Foo.bar)) # <-- marked line >> return q >> >> It should return path from the receiver node upwards to the root. >> >> The query works as expected without the marked line. However the order of >> result >> items is reversed when the marked line is present. I was under the impression >> that joinedload option should not have observable side-effects. >> >> Was I wrong? > > no, however I see something very conspicuously missing from your query above > with regard to ordering, which is an "order_by". You can never rely on the > ordering of results from a relational database if ORDER BY is not explicitly > present in the query. The means by which the database creates a query plan > out of the given clauses and executes them can change radically when extra > joins are added, thereby affecting the "natural" ordering of results.
Hm, I see. My train of thought: This particular query returns the path from a selected node to the root. Each iteration adds one row to the result set (one new parent). I thought that UNION ALL keeps the order intact and thus no order_by clause is needed. I guess I was wrong. I can add a depth/iteration column (via literal_column) and order_by it. However I still want the results to be a list of Node instances (i.e. without the added depth column). How can I write such a query? Thanks, Ladislav Lenart -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.