Is it possible to make child objects (many-to-one side) delete itself from 
the old parent's collection when it is added to a different parent? 
See the file attached. The old parent remains unaware that he doesn't have 
this child anymore.

P.S. session.expire() is an obvious solution but too heavy. I expect some 
event-based collection synchronization, much like backref (back_populates) 
connected collections.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
from sqlalchemy import create_engine, MetaData, Column, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base


engine = create_engine('mysql://user@localhost/probe')

Base = declarative_base(bind=engine)

Session = sessionmaker(bind=engine)
session = Session()


class User(Base):
    __tablename__ = 'user'
    name = Column(String(10), primary_key=True)
    address = relationship('Address', uselist=False, cascade='all,delete-orphan', back_populates='user')


class Address(Base):
    __tablename__ = 'address'
    addr = Column(String(20))
    username = Column(ForeignKey(User.name), primary_key=True)
    user = relationship('User', back_populates='address')


if __name__ == '__main__':
    joe, jef = session.query(User).all()
    if joe.name != 'joe':
        joe, jef = jef, joe

    assert joe.address is not None
    assert jef.address is None

    jef.address = joe.address

    # HERE IS THE PROBLEM: it's expected to become None
    assert joe.address is not None
    session.flush()
    assert joe.address is not None  # not even flush() helps

    # Here's how sample objects were created:
    # Base.metadata.create_all()
    # joe = User(name='joe')
    # jef = User(name='jef')
    # session.add_all((joe, jef))
    # joe.address = Address(addr='joe str')
    # session.commit()

Reply via email to