cascade deletes objects it shouldn't

Issue #445 resolved
Former user created an issue

A cascaded deletion will sometimes incorrectly delete objects that were previously related but no longer are.

#!/usr/bin/python

from sqlalchemy import *

engine = create_engine('sqlite://')
metadata = BoundMetaData(engine)
session = create_session(bind_to=engine)

_person = \
    Table('person', metadata,
          Column('person_id', Integer, primary_key=True),
          Column('name', String(20), nullable=False))

_item = \
    Table('item', metadata,
          Column('item_id', Integer, primary_key=True),
          Column('owner_id', Integer, ForeignKey(_person.c.person_id),
                 nullable=False),
          Column('name', String(20), nullable=False))

metadata.create_all()

class Person(object):
    pass

class Item(object):
    pass

mapper(Person, _person,
       properties = {'items': relation(Item, backref=backref('owner'),
                                       cascade='all, delete-orphan')})

mapper(Item, _item)

john = Person()
john.name = 'John'
session.save(john)

mary = Person()
mary.name = 'Mary'
session.save(mary)

chair = Item()
chair.name = 'Rocking Chair'
chair.owner = john
session.save(chair)

session.flush()

chair.owner = mary         # chair and john should no longer be related now

#session.flush()           # flushing here seems to solve the problem but shouldn't be necessary

session.delete(john)       # deletion incorrectly cascades to chair
print session.deleted      # prints set([chair](john,)) -- should print set([john](john))

Comments (1)

  1. Log in to comment