So this is actually a follow on from a question I posed quite a while back now:
http://groups.google.com/group/sqlalchemy/browse_thread/thread/4530dffffd3f5585/eb4638599b02577d?lnk=gst&q=Postgres+cascade+error#eb4638599b02577d So my approach to solving this problem was to use a MapperExtension, but it's giving me the error that I originally posted in this thread. I'm re-posting my previous code here for easy reference and testing by others (with one tiny mod to get rid of the optionparser code I had): --- #!/usr/bin/env python import sys import sqlalchemy as sa import sqlalchemy.orm session = sa.orm.scoped_session( sa.orm.sessionmaker(autoflush=False, transactional=True) ) mapper = session.mapper metadata = sa.MetaData() houseTable = sa.Table( 'house', metadata, sa.Column('id', sa.Integer, primary_key=True), ) ownerTable = sa.Table( 'owner', metadata, sa.Column('id', sa.Integer, primary_key=True), sa.Column('house_id', sa.Integer, sa.ForeignKey('house.id')), ) dogTable = sa.Table( 'dog', metadata, sa.Column('id', sa.Integer, primary_key=True), sa.Column('house_id', sa.Integer, sa.ForeignKey('house.id')), ) friendshipTable = sa.Table( 'friendship', metadata, sa.Column('id', sa.Integer, primary_key=True), sa.Column('owner_id', sa.Integer, sa.ForeignKey('owner.id')), sa.Column('dog_id', sa.Integer, sa.ForeignKey('dog.id')), ) class House(object): pass class Owner(object): pass class Dog(object): pass class Friendship(object): pass mapper( House, houseTable, properties = { "owners" : sa.orm.relation( Owner, cascade="delete-orphan" ), "dogs" : sa.orm.relation( Dog, cascade="delete-orphan" ), }, ) mapper( Owner, ownerTable, properties = { "friendships" : sa.orm.relation( Friendship, cascade="delete" ), }, ) mapper( Friendship, friendshipTable, properties = { "dog" : sa.orm.relation( Dog, uselist=False, cascade="all, delete-orphan" ), }, ) mapper(Dog, dogTable) if __name__ == "__main__": engine = sa.create_engine( "postgres://test:[EMAIL PROTECTED]/test", strategy="threadlocal", echo=True ) metadata.bind = engine session.configure(bind=engine) print "Creating tables" metadata.create_all() print "Seeding database" for i in range(10): House() session.flush() for house in sa.orm.Query(House).all(): for i in range(2): owner = Owner() house.owners.append(owner) session.flush() for house in sa.orm.Query(House).all(): for i in range(2): dog = Dog() house.dogs.append(dog) session.flush() for owner in sa.orm.Query(Owner).all(): for dog in sa.orm.Query(Dog).filter_by(house_id = owner.house_id).all(): friendship = Friendship() friendship.dog = dog owner.friendships.append(friendship) session.commit() owner = sa.orm.Query(Owner).first() for f in owner.friendships: print "FRIENDSHIP: %s || DOG: %s" % (f.id, f.dog.id) print "Deleting owner" session.delete(owner) session.flush() session.commit() 2008/11/27 David Harrison <[EMAIL PROTECTED]>: > Sorry, I should probably have mentioned that C isn't the only object > that maps A, so a cascade doesn't work. > > 2008/11/27 <[EMAIL PROTECTED]>: >> >> i'm not expert on these, but i think u need something like >> cascade='all' on your relation, _instead_ of the mapperExt. check the >> docs about possible settings. the mapperExt fires too late and the >> session flush-plan gets surprised. >> >> On Thursday 27 November 2008 08:15:04 David Harrison wrote: >>> Hey all, >>> >>> I've got a situation where I have 2 object A and B, and a third >>> object C that has a foreign key reference to both A and B. I can >>> have many C's that map to the same A. >>> >>> Now I've implemented a MapperExtension for C that has an >>> after_delete function, and that function checks to see if the A >>> that the deleted C was mapped to has any other mappings, and if >>> there are no other mappings left, deletes the A. >>> >>> Now this works fine if I'm just deleting C's directly, however as >>> soon as this happens during a cascade delete from some other object >>> D that happens to have a mapping to C I get the below error - I'm >>> assuming this is because sqlalchemy has a test condition that >>> doesn't see my mapper coming, and freaks out when extra rows get >>> nuked. >>> >>> "ConcurrentModificationError: Deleted rowcount 0 does not match >>> number of objects deleted 4" >>> >>> Help ? >>> >>> Cheers >>> Dave >>> >>> >> >> >> >> >> > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---