From: Mike Bayer Date: Fri, 5 Jan 2007 04:56:57 +0000 (+0000) Subject: - fix to post_update to insure rows are updated even for non insert/delete scenarios X-Git-Tag: rel_0_3_4~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4771a156a3b4ae233a8efd9b7741e09bebfe6d87;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - fix to post_update to insure rows are updated even for non insert/delete scenarios [ticket:413] --- diff --git a/CHANGES b/CHANGES index 8b76728411..4b40af5182 100644 --- a/CHANGES +++ b/CHANGES @@ -19,7 +19,8 @@ item lists [ticket:407] required for firebird, not a bad idea for others [ticket:408] - Firebird fix to autoload multifield foreign keys [ticket:409] - Firebird NUMERIC type properly handles a type without precision [ticket:409] - +- fix to post_update to insure rows are updated even for non insert/delete scenarios +[ticket:413] 0.3.3 - string-based FROM clauses fixed, i.e. select(..., from_obj=["sometext"]) diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py index a49d216ae0..301be81742 100644 --- a/lib/sqlalchemy/orm/dependency.py +++ b/lib/sqlalchemy/orm/dependency.py @@ -108,7 +108,7 @@ class DependencyProcessor(object): given related object list contains INSERTs or DELETEs.""" if obj is not None and self.post_update: for x in related: - if x is not None and (uowcommit.is_deleted(x) or not hasattr(x, '_instance_key')): + if x is not None: uowcommit.register_object(obj, postupdate=True, post_update_cols=self.syncrules.dest_columns()) break diff --git a/test/orm/cycles.py b/test/orm/cycles.py index eef1e6e096..2c6a3541cf 100644 --- a/test/orm/cycles.py +++ b/test/orm/cycles.py @@ -715,11 +715,56 @@ class SelfReferentialPostUpdateTest(AssertMixin): "UPDATE node SET next_sibling_id=:next_sibling_id WHERE node.id = :node_id", lambda ctx:{'next_sibling_id':stories.id, 'node_id':about.id} ), + ( + "UPDATE node SET next_sibling_id=:next_sibling_id WHERE node.id = :node_id", + lambda ctx:{'next_sibling_id':None, 'node_id':cats.id} + ), ( "DELETE FROM node WHERE node.id = :id", lambda ctx:[{'id':cats.id}] ), ]) + +class SelfReferentialPostUpdateTest2(AssertMixin): + def setUpAll(self): + global metadata, a_table + metadata = BoundMetaData(testbase.db) + a_table = Table("a", metadata, + Column("id", Integer(), primary_key=True), + Column("fui", String()), + Column("b", Integer(), ForeignKey("a.id")), + ) + a_table.create() + def tearDownAll(self): + a_table.drop() + def testbasic(self): + """test that post_update remembers to be involved in update operations as well, + since it replaces the normal dependency processing completely [ticket:413]""" + class a(object): + def __init__(self, fui): + self.fui = fui + + mapper(a, a_table, properties={ + 'foo': relation(a, remote_side=[a_table.c.id], post_update=True), + }) + + session = create_session() + + f1 = a("f1") + session.save(f1) + session.flush() + + f2 = a("f2") + f2.foo = f1 + # at this point f1 is already inserted. but we need post_update + # to fire off anyway + session.save(f2) + session.flush() + + session.clear() + f1 = session.query(a).get(f1.id) + f2 = session.query(a).get(f2.id) + assert f2.foo is f1 if __name__ == "__main__": testbase.main()