Hello,

I am using SQLAlchemy V0.8 and the question is related to the ORM. It is 
about the models in memory (I think the kind of database used is not 
relevant). 

To explain my issue, I'll consider the following basic *OneToMany* declarative 
example from the documentation with a backref relationship (with __repr__ 
functions for debugging):
 

class Parent(Base):
    __tablename__ = 'parent'
    parentId = Column(Integer, primary_key = True)
    name = Column(String(90))

 

    children = relationship("Child", backref=backref('parent'))

    def __repr__(self):
        return "<Parent('%s','%s')>" % (self.name, self.children)

class Child(Base):

__tablename__ = 'child'

elementId = Column(Integer, primary_key = True)

name = Column(String(90))

parentId = Column(Integer, ForeignKey("parent.parentId"))

 

def __repr__(self):

        if self.parent is not None:

            parentName = self.parent.name

        else:

            parentName = "None"

        return "<Child('%s','%s')>" % (self.name, parentName) 



If the parent attribute of a child is changed from *parent1 *to *parent2*, 
not only is the child added to the children of the new parent *parent2*, it 
is also removed from the collection of the old parent *parent1*. Example:

child.parent = parent1

print parent1
print parent2
print child
print '================================='
child.parent = parent2
print parent1
print parent2
print child


 yields the following output:

>>> <Parent('Parent 1','[<Child('Child 1','Parent 1')>]')>
>>> <Parent('Parent 2','[]')>
>>> <Child('Child 1','Parent 1')>
>>> =================================
>>> <Parent('Parent 1','[]')>
>>> <Parent('Parent 2','[<Child('Child 1','Parent 2')>]')>
>>> <Child('Child 1','Parent 2')>


However, if the child is appended to group2.children when it has group1 as 
a parent, the child is added to the children collection of group2 *but not 
removed from the children collection of group1. *Example:

child.parent = parent1
print parent1
print parent2
print child
print '================================='
parent2.children.append(child)
print parent1
print parent2
print child

The following output shows the issue:

<Parent('Parent 1','[<Child('Child 1','Parent 1')>]')>
<Parent('Parent 2','[]')>
<Child('Child 1','Parent 1')>
=================================
<Parent('Parent 1','[<Child('Child 1','Parent 2')>]')>
<Parent('Parent 2','[<Child('Child 1','Parent 2')>]')>
<Child('Child 1','Parent 2')>


I am quite new to SQLAlchemy and I don't know if this is expected behavior. 
I nevertheless dare to say that I find the states of the objects in memory 
to be incoherent as child1 no longer has parent1 as its parent while 
parent1 still thinks that it has child1 as a child. Moreover, it is not 
clear what happens when the objects are persisted to the database (what 
would the value of child1.parentId be?)
Am I missing some configuration that need to be done to solve this issue? 
Or is this to accommodate some edge case?

I have looked at *single_parent *but this forbids changing the parent, 
while the intuitive behavior would be (IMHO) the exact same as changing the 
parent attribute to guarantee the symmetry between a relationship and its 
backref.

Thanks in advance for your kind reply.

Edouard

-- 
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/groups/opt_out.


Reply via email to