[sqlalchemy] Re: Multiple joins and cascading delete

2007-01-18 Thread Michael Bayer


the ImageComment mapper is superfluous to the example.  you should
generally not map a class to a table, then also use that table as the
secondary join in another mapping; since changes to one wont get
reflected in the other.  If you want to use ImageComment, then you need
to use the association object pattern and not the secondary join
argument; the two patterns are mutually exclusive.  for this email, ill
use the secondary table pattern.

SA does not keep track of all the collections that an entity belongs
to.  so when you say session.delete(c), it has no idea that c is part
of a comments collection on an Image, so no operation occurs.

the solution is to remove the comment from the comments collection:

i = session.query(Image).get(i.id)
c = session.query(Comment).get(c.id)
i.comments.remove(c)
session.delete(c)
session.flush()

if youd like to skip the separate remove() and delete() operation, you
can use delete-orphan.  for some reason, using delete-orphan with a
many-to-many relationship is requiring a bi-directional reference for
it to work properly...ive just added ticket # 427 for this which will
be fixed by tomorrow and the images backref you see below will no
longer be required.

imageMapper = mapper(Image, ImageTable,
   properties={'comments': relation(Comment,
secondary=ImageCommentTable, lazy=False, cascade=all, delete-orphan,
backref=images)}
   )

session = create_session()
i = Image(new)
session.save(i)
session.flush()
c = Comment(new comment)
i.comments.append(c)
session.flush()

i = session.query(Image).get(i.id)
c = session.query(Comment).get(c.id)
i.comments.remove(c)
session.flush()
session.clear()

notice above that the Comment is automatically added to the session
when its appended to the Image, this is due to the save-update
cascade present on the comments relation.  If you try to save() the
Comment by itself in the session, without it being attached to any
Image, and then flush(), thats an invalid operation since its an orphan
(not attached to anything).  then we remove the comment from the parent
Image object, and the delete of both the Comment and the many-to-many
record succeeds.


--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Multiple joins and cascading delete

2007-01-18 Thread Michael Bayer


ticket 427 is fixed in rev 2216.  so using the trunk or 0.3.4 when i
get around to releasing, this is the program:

imageMapper = mapper(Image, ImageTable,
   properties={'comments': relation(Comment,
secondary=ImageCommentTable, lazy=False, cascade=all, delete-orphan)}
   )

session = create_session()
i = Image(new)
session.save(i)
session.flush()
c = Comment(new comment)
session.save(c)
i.comments.append(c)
session.flush()

i = session.query(Image).get(i.id)
c = session.query(Comment).get(c.id)
i.comments.remove(c)
session.flush()
session.clear()


--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---