I'm having a very strange issue with delete-orphan where I insert an item and 
its parent becomes and orphan and gets deleted on session.flush(). I tried to 
make a test case that reproduces the error, but was not successful. I also 
tried to trace the problem to see where its originating. I payed particular 
attention to InstrumentedAttribute.sethasparent(), 
InstrumentedAttribute.hasparent() and Mapper._is_orphan().

First some background:

<class 'orderentry.model.Order'> is the parent type of 
<OrderLineItem id=82>, which is the parent instance of 
<OrderLineItemSize id=None>, which is the new item being inserted


Here's the pdb session where things start to get strange:


> .../lib/sqlalchemy/attributes.py(42)sethasparent()
-> if item is not None:
(pdb) n
> .../lib/sqlalchemy/attributes.py(43)sethasparent()
-> item._state[('hasparent', id(self))] = value
(pdb) item
<OrderLineItem id=82>
(pdb) id(self)
21105808 <----- NOTE THIS IS THE child's backref PROPERTY ID
(pdb) u
> .../lib/sqlalchemy/attributes.py(186)set()
-> self.sethasparent(value, True)
(pdb) obj
<OrderLineItemSize id=None>


Explanation: <OrderLineItem id=82>._state gets a ('hasparent', 21105808): True, 
which refers to its sizes[0].lineItem UOWProperty instance. I.E. the child's 
backref property is registered as the parent's parent property. I believe 
that's a bug...


Here's the debug session where errors pop up during flush() due to 
<OrderLineItem id=82> being flagged as an orphan even though it is not an 
orphan at all

> .../lib/sqlalchemy/orm/mapper.py(144)_is_orphan()
-> for (key,klass) in self.delete_orphans:
(pdb) n
> .../lib/sqlalchemy/orm/mapper.py(145)_is_orphan()
-> if not getattr(klass, key).hasparent(obj):
(pdb) 
> .../lib/sqlalchemy/orm/mapper.py(146)_is_orphan()
-> return True
(pdb) obj
<OrderLineItem id=82>
(pdb) key
'lineItems'
(pdb) klass
<class 'orderentry.model.Order'>
(pdb) obj.sizes[0]
<OrderLineItemSize id=None>
(pdb) obj.sizes[0].lineItem
<OrderLineItem id=82>
(pdb) obj._state
{('hasparent', 21105808): True, ... )}
(pdb) id(type(obj.sizes[0]).lineItem)
21105808  <----- NOTE THIS IS THE child's backref PROPERTY ID


Explanation: <OrderLineItem id=82> is checked for orphan-hood using the 
'lineItems' property of Order (i.e. the correct parent property). The line item 
has a 'hasparent' key in its _state, but its the wrong one (i.e. the hasparent 
entry in _state points to the child's backref property, not the parent 
property).

I realize this is very complicated and hard to follow. Is there something else 
I can do to help find the problem?

Thanks,

~ Daniel


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users

Reply via email to