You've changed the session object though, this is for a web app so the
scoped session is what I need.  That then immediately breaks all the
session.save calls.

2008/11/27  <[EMAIL PROTECTED]>:
>
> so my version does work on postgres too (did u try it?)..
> at least finishes with no errors.
> or should there be other checks? like what's left in each table?
>
> On Thursday 27 November 2008 10:30:04 David Harrison wrote:
>> Postgres is the intended deployment platform so it really does need
>> to work on Postgres, that said last time I dug into this I found
>> that SQLite is less strict on enforcing key constraints where
>> Postgres isn't, so technically Postgres is right to complain.
>>
>> 2008/11/27  <[EMAIL PROTECTED]>:
>> > 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/4
>> >>530
>> >> dffffd3f5585/eb4638599b02577d?lnk=gst&q=Postgres+cascade+error#e
>> >>b463 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to