this is definitely the behavior, and it should probably be improved. I made it raise an explicit exception so at least the issue is easy to spot, as opposed to it making it all the way into the commit() where things really get messed up. i would imagine the same problem occurs if you remove the backrefs ?
Dale Sedivec wrote: > [Sorry if this makes it onto the list twice. I posted through > Gmane NNTP and was told the message was sent to moderation. I haven't > seen it appear on the list yet.] > > Greetings. I've got a database with a parent/children > relationship (one-to-many, to clarify). When a parent is deleted, all > children should be deleted; this is reflected in the schema (ON DELETE > CASCADE) as well as in the SA relationship (private=True). > > However, I'm running into problems in the case where a > child's parent needs to be changed. I've demonstrated this in the > test script included below. As near as I can tell the reassignment > works like: > > (1) Delete child from old parent. > (a) Parent says "my children are private, so delete the > child." > (2) Add child to new parent, resulting in an exception because the > child has been deleted. > > It looks to me like this trouble may originate around > GenericBackrefExtension.set(), where it does a "remove" followed by an > "append." I tried to step through this code but I wasn't able to > follow it. > > Would it be possible to modify this code (or modify elsewhere) > so that the calls to remove the object from the parent know that the > child is not being removed, but reassigned to a different parent? > I.e., ignore the private=True for cases of reassigning a parent? > > Or, alternatively, will anyone kindly suggest a recipe for > getting around this problem? The only way I've found is something > roughly like (using variables from below test): > > child.foo_id = new_parent.id > child.commit() # Actually issues SQL UPDATE statement > objectstore.refresh(child) # If you don't refresh, child.foo is None > assert child.new is new_parent > > Thanks for any assistance, and thanks for SA. > > Dale > > ---- > > from sqlalchemy import * > > # -- PostgreSQL 8.1.3, using the following schema: > # > # CREATE TABLE foo (id INTEGER PRIMARY KEY); > # CREATE TABLE bar (id INTEGER PRIMARY KEY, > # foo_id INTEGER REFERENCES foo (id) NOT NULL > # ON DELETE CASCADE); > # INSERT INTO foo VALUES (1); > # INSERT INTO foo VALUES (2); > # INSERT INTO bar VALUES (3, 1); > > db_uri = "postgres://database=oit_pwdb&user=oit_pwdb&password=qipiY24P" > engine = create_engine(db_uri, echo=True) > > foos = Table("foo", engine, autoload=True) > bars = Table("bar", engine, autoload=True) > > class Foo (object): pass > assign_mapper(Foo, foos) > class Bar (object): pass > assign_mapper(Bar, bars) > > cascade_mappers(Foo, Bar) > Foo.mapper.add_property("bars", relation(Bar, backref="foo", > private=True)) > > # Actual problem section is here. > child = Bar.get(3) > old_parent = Foo.get(1) > assert child.foo is old_parent, "test setup failed" > new_parent = Foo.get(2) > child.foo = new_parent > # The above statement raises the following exception: > # > # File > # > ".../python2.4/site-packages/SQLAlchemy-0.1.5-py2.4.egg/sqlalchemy/mapping/unitofwork.py", > # line 47, in list_value_changed > # raise InvalidRequestError("re-inserting a deleted value into a > list") > > # Never get here. > child.commit() > assert child.foo_id == new_parent.id, "parent change failed" > > > ------------------------------------------------------- > This SF.Net email is sponsored by xPML, a groundbreaking scripting > language > that extends applications into web and mobile media. Attend the live > webcast > and join the prime developer group breaking into this new coding > territory! > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 > _______________________________________________ > Sqlalchemy-users mailing list > Sqlalchemy-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users > ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 _______________________________________________ Sqlalchemy-users mailing list Sqlalchemy-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users