[sqlalchemy] Re: Cascade-Delete causes AssertionError (Tries to blank-out primary key ...)
On 14 Feb., 01:02, Michael Bayer [EMAIL PROTECTED] wrote: OK its fixed in r2314. the cascade from User.meta does take effect, This was fast ! I checked out r2314, and my old code (without delete-orphan) is working now. The only problem: I started to write a little beginners manual for the Parent/Child/Cascade issue, and now I have to rewrite it (how about re- introducing the bug ? ;-) ) Thank you very much. Ruben --~--~-~--~~~---~--~~ 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: Cascade-Delete causes AssertionError (Tries to blank-out primary key ...)
On 12 Feb., 18:17, Luke Stebbing [EMAIL PROTECTED] wrote: Right, delete-orphan is what adds the lifecycle relationship between parent and child. It means that the child can't exist without a parent. That lets SA know that it should eliminate the child rather than trying to null out the relationship. The misunderstanding is obviously the question which one is the child, which is the parent. The ORM , as far as I understand, does never care for the table structure. Particularly, it plays no role which table has the Foreign Key. Therefore, I expected the following declaration mapper(Userdata, t_userdata, properties = { myuser:relation(User,backref=backref(meta,cascade=delete)) }) to define a cascade where User.delete triggers a Userdata.delete. (I expected this because the cascade keyword is in the backref, not in the relation !) But now it seems to me that it doesn't matter where I define the cascade. I tested some cases and obviously the rule is the following: The fist object that defines a property relation, becomes the parent. Subsequent backref, and even subsequent addProperty(foo:relation ...) on the child play no role anymore. It this right ? Btw, can I find this rule (who is the Parent) somewhere in the API docs ? Ruben --~--~-~--~~~---~--~~ 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: Cascade-Delete causes AssertionError (Tries to blank-out primary key ...)
OK its fixed in r2314. the cascade from User.meta does take effect, its just that the combination primary key/foreign key column on the t_userdata table was being blanked out when the deletion of the User took place, i.e. it was not checking first that the Userdata was also being deleted. usually the delete-orphan cascade would be present which was hiding the issue. in the spirit of svilen I added a more exhaustive set of tests than I usually do, for various scenarios in this category, and located some variants of the same issue in the process. On Feb 13, 6:01 pm, Michael Bayer [EMAIL PROTECTED] wrote: On Feb 13, 3:26 pm, Nebur [EMAIL PROTECTED] wrote: Therefore, I expected the following declaration mapper(Userdata, t_userdata, properties = { myuser:relation(User,backref=backref(meta,cascade=delete)) }) to define a cascade where User.delete triggers a Userdata.delete. (I expected this because the cascade keyword is in the backref, not in the relation !) it does. this is a bug in SA. fix will be up shortly. --~--~-~--~~~---~--~~ 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: Cascade-Delete causes AssertionError (Tries to blank-out primary key ...)
Right, delete-orphan is what adds the lifecycle relationship between parent and child. It means that the child can't exist without a parent. That lets SA know that it should eliminate the child rather than trying to null out the relationship. You probably want all so that all actions performed on the parent will propagate to the child, which will remove the need to save children directly. See here also: http://www.sqlalchemy.org/docs/unitofwork.myt#unitofwork_cascade Cheers, Luke On Feb 11, 1:49 pm, Nebur [EMAIL PROTECTED] wrote: The minimum correction of my above code seems to be 2 lines: 1.The cascade rule changed from delete into all,delete-orphan No, it turned out there is a still smaller change: The cascade rule changed from delete into delete, delete-orphan will work, too. The delete-orphan makes up the difference. Ruben --~--~-~--~~~---~--~~ 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: Cascade-Delete causes AssertionError (Tries to blank-out primary key ...)
See http://www.sqlalchemy.org/docs/ datamapping.myt#datamapping_relations_lifecycle I think you want a parent-child relationship between User and Userdata. Here's how I would change it (disclaimer: I'm new to SA myself): class User(object): pass class Userdata(object): pass ### we'll let SQLAlchemy update the relationship automatically instead of setting it manually if __name__==__main__: db = create_engine(mysql://[EMAIL PROTECTED]/test_cascade) session = create_session() metadata = BoundMetaData(db) t_user = Table(user,metadata, Column(id,Integer,primary_key=True), ) t_userdata = Table(userdata,metadata, Column(user_id,Integer,ForeignKey(user.id),primary_key=True), ) metadata.create_all() ### we create the relationship here instead, for clarity. uselist=False on the relation and the backref makes it one-to-one. Compare to the example in the link I gave mapper(User, t_user, properties = { userdata: relation(Userdata, uselist=False, cascade=all, delete-orphan, backref=backref(myuser, uselist=False)) }) mapper(Userdata, t_userdata) # create 1 instance of each object: user1 = User() session.save(user1) session.flush() user1.userdata = Userdata() ### add userdata to user, relationship is automatically created session.flush() # now delete the user session.delete(user1) session.flush() Cheers, Luke On Feb 11, 9:44 am, Nebur [EMAIL PROTECTED] wrote: The example below raises an: sqlalchemy.exceptions.AssertionError: Dependency rule tried to blank- out primary key column 'userdata.user_id' on instance '[EMAIL PROTECTED]' The code creates 2 objects having a 1:1 relation with cascade-delete. The ForeignKey is declared as a primary key. This seems to cause the Error. Versions: Python 2.4, SA 0.3.1, SA 0.3.4 class User(object): pass class Userdata(object): def __init__(self, user): self.user_id = user.id if __name__==__main__: db = create_engine(mysql://[EMAIL PROTECTED]/test_cascade) session = create_session() metadata = BoundMetaData(db) t_user = Table(user,metadata, Column(id,Integer,primary_key=True), ) t_userdata = Table(userdata,metadata, Column(user_id,Integer,ForeignKey(user.id),primary_key=True), ) metadata.create_all() mapper(User, t_user) mapper(Userdata, t_userdata, properties = { myuser:relation(User,backref=backref(meta,cascade=delete)) }) # create 1 instance of each object: user1 = User() session.save(user1) session.flush() data1 = Userdata(user1) session.save(data1) session.flush() # now delete the user, # expecting the cascade to delete userdata,too: session.delete(user1) session.flush() #AssertionError: Dependency rule tried to blank- out ... I can workaround this error by using a separate primary key in table userdata: t_userdata = Table(userdata,metadata, Column(id,Integer,primary_key=True), Column(user_id,Integer,ForeignKey(user.id)), ) and everything works fine. I'm wondering whether this is an SA bug, or a bad table design ? Thanks and regards, Ruben --~--~-~--~~~---~--~~ 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: Cascade-Delete causes AssertionError (Tries to blank-out primary key ...)
Luke, your example is a great speed-up for me learning SA ! And my code is working fine now. I' m still looking what exactly makes the AssertionError disappear. (Well, your other changes (uselist=False etc.) are clearly an improvement. Still want to find out the cause of the error) The minimum correction of my above code seems to be 2 lines: 1.The cascade rule changed from delete into all,delete-orphan 2.This in turn requires to maintain the relation in one of the objects: after: session.save(data1) data1.myuser = user1 # alternatively user1.meta.append(data1) will work as well I still don't understand why the ORM strictly requires all, delete- orphan here, and why delete ends up in the AssertionError. I think all stands for delete, save-update, refresh-expire, merge, expunge. But none of these rules seems to play a role is this example. (I _must_ be wrong here...) Any hint is really appreciated. Ruben --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---