Probably autoflush when you hit .children - you'd see it in the stack trace
Sent from my iPhone On Apr 12, 2012, at 3:47 AM, lars van gemerden <l...@rational-it.com> wrote: > The question was based on a misconception on my part (in a visual > representation of a tree, while dragging a node you drag the whole > subtree with it, so you can't drop a node in it's own subtree). > > Sorry about that ... > > > PS: Checked that when updating the children (via append) the exception > occurs right away (is there a flush happening in the background?), > while when updating the parent, the exception happens during the flush > afterwards. > > On Apr 11, 5:41 pm, Michael Bayer <mike...@zzzcomputing.com> wrote: >> On Apr 11, 2012, at 3:34 AM, lars van gemerden wrote: >> >> >> >> >> >> >> >> >> >>> Hi all, >> >>> I am looking for a way to append a child to a tree like structure. I >>> am using adjacency to represent the tree. >> >>> Let's say I have a relationship configured with: >> >>> children = relationship(TreeNode, >>> primaryjoin = "TreeNode.id == >>> TreeNode.parent_id", >>> backref = backref( "parent", >>> remote_side=[TreeNode.id]), >>> cascade = "all, delete-orphan", >>> use_list = True) >> >>> and I do: >> >>> t1 = TreeNode() >>> t2 = TreeNode(parent = t1) >>> t3 = TreeNode(parent = t2) >> >>> then i can set: >> >>> t1.parent = t3, >> >>> without problem, but: >> >>> t3.children.append(t1) >> >>> gives a CircularDependencyError, while i would like this to give the >>> same result as t1.parent = t3, perhaps by altering the behaviour of >>> Treenode.children.append. >> >>> Am I missing something? >>> Is there some way to arrange for this? >> >> t1.parent = t3 means you aren't persisting a tree anymore - it's no longer a >> hierarchy, since t3 is a descendant of t1 already via t2. It's a cycle. >> >> The exception on the "children" side is probably because mutating "children" >> has the effect of both t3 and t1 being considered in the flush (due to >> t3.children as well as t1.parent_id changing), whereas t1.parent = t3 does >> not actually consider "t3" to modified. You'd still get a cycle if you >> created everything via "x.parent=y" at once (below I just put it into the >> adjacency_list.py example - boom): >> >> node = TreeNode('rootnode') >> n1 = TreeNode('node1', parent=node) >> n2 = TreeNode('node2', parent=n1) >> node.parent = n2 >> session.add(node) >> session.flush() >> >> sqlalchemy.exc.CircularDependencyError: Circular dependency detected. >> Cycles: ... >> >> though I wasn't able to reproduce the behavior being different by mutating >> children vs. the parent....I'm sure with more digging I could figure that >> out. But in any case, you aren't safe from cycles if you're building them, >> the usual way to insert rows with cycles to themselves is to use the >> post_update feature described >> athttp://docs.sqlalchemy.org/en/latest/orm/relationships.html#rows-that.... >> You probably need to put it on both sides in this case as the unit of work >> code will consider one or both of the "children" or "parent" relationships >> in a particular flush depending on where it sees changes. > > -- > 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. > -- 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.