On 8/27/15 2:27 PM, [email protected] wrote:
Having an adjacency list tree (actually, in my case it's a DAG) model
it's easy to write a recursive CTE which returns a list of the nodes
together with their level or path from the root, and applying filters
is also no problem. However, I couldn't find in the documentation and
previous discussions any information about how to fill a proper
hierarchy this way? I mean a kind of eager loading, like
root.children[i].children[i]..., with arbitrary number of levels. All
the data required to build this hierarchy is present in the CTE
results, so it should be possible.
yes so, you need to piece together the structure manually.
e.g.:
all_objects = session.query(Node).filter(...CTE
stuff...).order_by(Node.parent_id, Node.id).all()
then the rest I cut-and-paste more or less from
https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/DisjointEagerLoading,
I'm using groupby here but that relies on the results being ordered by
parent_id, and also assumes every node is only a member of exactly one,
or zero, collections. If it's more complicated than that in your
structure, just maintain a dictionary of all collections and build them
all up keyed to Node.id as they need to be:
from itertools import groupby
children = dict(
(k, list(v)) for k, v in groupby(
all_objects, lambda node: node.parent_id
)
)
then you connect the collections to their objects in one step like this:
from sqlalchemy.orm import attributes
for node in all_objects:
attributes.set_committed_value(node, "children",
children.get(node.id, ()))
Of course, in a simple case I could just use joinedload with the depth
equal to the longest path length, but adding some filtering requires
explicit aliased joins with contains_eager which can greatly increase
the code complexity: in my case I have many-to-many relationships as
the structure is a DAG (not a tree), and I also need to load two more
relationship (like root.children[i].child.some_properties) which I
join (and alias, and add contains_eager for it) for each level.
What's the preferred solution for such problems?
--
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
To post to this group, send email to [email protected]
<mailto:[email protected]>.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.