and what that shoud do? attached is a changed version... do see if that's what u want (it's sqlite, with plain session). the only real change is cascade=all,delete-orphan on house.owners... but i just unintentionaly guessed it.
On Thursday 27 November 2008 09:51:38 David Harrison wrote: > 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/4530 >dffffd3f5585/eb4638599b02577d?lnk=gst&q=Postgres+cascade+error#eb463 >8599b02577d > > 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 [email protected] 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 -~----------~----~----~----~------~----~------~--~---
f.py
Description: application/python
