+1
I needed this in a project and wrote the following code for it. I'm
not sure how well this would scale to more levels (how deep down it
goes, which is limited) and number of objects in the tree, but it
works okay for what I'm doing.
Example usage:
query_children(
context,
more_conditions={'type': 'mytype'},
).order_by(MyType.name)
Here's the code:
def children_ids(context, levels=3, more_conditions=None):
selects = []
for level in range(levels):
alias = Node.__table__
conditions = [Node.__table__.
c.id ==
context.id]
for depth in range(level + 1):
alias, old_alias = Node.__table__.alias(), alias
conditions.append(alias.c.parent_id ==
old_alias.c.id)
if more_conditions:
for key, value in more_conditions.items():
conditions.append(getattr(alias.c, key) == value)
selects.append(select([
alias.c.id], and_(*conditions)))
sel_union = selects.pop(0).alias().select()
for sel in selects:
sel_union = sel_union.union(sel).alias().select()
return sel_union
def query_children(context, levels=3, more_conditions=None):
return DBSession.query(Node).filter(
Node.id.in_(children_ids(context, levels, more_conditions)))
Daniel