Re: [sqlalchemy] Cascade delete-orphan: reattach child to another parent

2018-03-31 Thread Serhii Mozghovyi
Many thanks!

On Wednesday, March 28, 2018 at 6:42:16 PM UTC+3, Mike Bayer wrote:
>
> the backrefs intentionally don't keep fanning deep into object graph 
> for this kind of thing, so if you want it to go one hop further you 
> can add an event to do that directly: 
>
> from sqlalchemy import event 
> from sqlalchemy.orm import attributes 
>
>
> @event.listens_for(Address.user, "set") 
> def _intercept_set(target, value, oldvalue, initiator): 
>
> if isinstance(oldvalue, User) and "address" in oldvalue.__dict__: 
> attributes.set_committed_value(oldvalue, "address", None) 
>
>
> the "set_committed_value" is to avoid triggering any new events which 
> will cause a recursion overflow. 
>
>
>
> On Wed, Mar 28, 2018 at 10:49 AM, Serhii Mozghovyi <egna...@gmail.com 
> > wrote: 
> > 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+...@googlegroups.com . 
> > To post to this group, send email to sqlal...@googlegroups.com 
> . 
> > Visit this group at https://groups.google.com/group/sqlalchemy. 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
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.


[sqlalchemy] Cascade delete-orphan: reattach child to another parent

2018-03-28 Thread Serhii Mozghovyi
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()