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.

Reply via email to