[Sqlalchemy-tickets] Issue #4131: Object deleted by delete-orphan not marked as deleted (zzzeek/sql
Brought to you by:
zzzeek
From: erdnaxeli <iss...@bi...> - 2017-11-07 18:07:14
|
New issue 4131: Object deleted by delete-orphan not marked as deleted https://bitbucket.org/zzzeek/sqlalchemy/issues/4131/object-deleted-by-delete-orphan-not-marked erdnaxeli: Hi, When removing an object from a collection, if this object is deleted because of `cascade="all, delete-orphan'`, the object is not marked as deleted. ``` #!/usr/bin/env python from sqlalchemy import Column, ForeignKey, Integer, String, create_engine, event from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.inspection import inspect from sqlalchemy.orm import backref, relationship, sessionmaker engine = create_engine('sqlite:///:memory:', echo=True) Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) class Pet(Base): __tablename__ = 'pets' id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('users.id'), nullable=False) name = Column(String) user = relationship( 'User', backref=backref('pets', cascade='all, delete-orphan') ) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() @event.listens_for(Session, 'after_flush') def do_something_with_updated_objects(session, flush_context): for obj in session.dirty: print(obj.name) i = inspect(obj) if not i.deleted: session.refresh(obj) print('> Create objects') george = User(id=1, name='George') rex = Pet(id=1, name='Rex') george.pets.append(rex) session.add(george) session.commit() print('> Remove Rex') george = session.query(User).filter_by(name='George').scalar() assert(len(george.pets) == 1) rex = george.pets[0] # removing Rex will actually delete it, because of delete-orphan george.pets.remove(rex) session.add(george) session.commit() george = session.query(User).filter_by(name='George').scalar() assert(len(george.pets) == 0) ``` Output: ``` > Create objects 2017-11-07 19:03:07,351 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 2017-11-07 19:03:07,352 INFO sqlalchemy.engine.base.Engine INSERT INTO users (id, name) VALUES (?, ?) 2017-11-07 19:03:07,352 INFO sqlalchemy.engine.base.Engine (1, 'George') 2017-11-07 19:03:07,352 INFO sqlalchemy.engine.base.Engine INSERT INTO pets (id, user_id, name) VALUES (?, ?, ?) 2017-11-07 19:03:07,353 INFO sqlalchemy.engine.base.Engine (1, 1, 'Rex') 2017-11-07 19:03:07,353 INFO sqlalchemy.engine.base.Engine COMMIT > Remove Rex 2017-11-07 19:03:07,353 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 2017-11-07 19:03:07,354 INFO sqlalchemy.engine.base.Engine SELECT users.id AS users_id, users.name AS users_name FROM users WHERE users.name = ? 2017-11-07 19:03:07,354 INFO sqlalchemy.engine.base.Engine ('George',) 2017-11-07 19:03:07,354 INFO sqlalchemy.engine.base.Engine SELECT pets.id AS pets_id, pets.user_id AS pets_user_id, pets.name AS pets_name FROM pets WHERE ? = pets.user_id 2017-11-07 19:03:07,354 INFO sqlalchemy.engine.base.Engine (1,) 2017-11-07 19:03:07,355 INFO sqlalchemy.engine.base.Engine DELETE FROM pets WHERE pets.id = ? 2017-11-07 19:03:07,355 INFO sqlalchemy.engine.base.Engine (1,) Rex 2017-11-07 19:03:07,356 INFO sqlalchemy.engine.base.Engine SELECT pets.id AS pets_id, pets.user_id AS pets_user_id, pets.name AS pets_name FROM pets WHERE pets.id = ? 2017-11-07 19:03:07,356 INFO sqlalchemy.engine.base.Engine (1,) 2017-11-07 19:03:07,356 INFO sqlalchemy.engine.base.Engine ROLLBACK Traceback (most recent call last): File "t.py", line 61, in <module> session.commit() File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 921, in commit self.transaction.commit() File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 461, in commit self._prepare_impl() File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 441, in _prepare_impl self.session.flush() File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2192, in flush self._flush(objects) File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2312, in _flush transaction.rollback(_capture_exception=True) File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__ compat.reraise(exc_type, exc_value, exc_tb) File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2280, in _flush self.dispatch.after_flush(self, flush_context) File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/event/attr.py", line 218, in __call__ fn(*args, **kw) File "t.py", line 43, in do_something_with_updated_objects session.refresh(obj) File "/home/amorigno/bacasable/delete/.venv/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1474, in refresh instance_str(instance)) sqlalchemy.exc.InvalidRequestError: Could not refresh instance '<Pet at 0x7f21393a5490>' ``` I would expect `i.deleted` to be `True`. SQLAlchemy==1.1.15 Python 2.7.6 |