From: Mike Bayer Date: Wed, 7 Nov 2007 01:36:16 +0000 (+0000) Subject: adjusted "blank out primary key" rule to check for "allow_null_pks" on target mapper... X-Git-Tag: rel_0_4_1~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1a9a96ba541c8ec12864259dd2f076ef6e056c8;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git adjusted "blank out primary key" rule to check for "allow_null_pks" on target mapper. this was revealed by recent attributes.py change in r3695 that causes a value of "None" to register as part of the attribute history's added_items() collection (i.e. since AttributeHistory compares against NO_VALUE instead of None). --- diff --git a/CHANGES b/CHANGES index e8b94b21cc..b849557463 100644 --- a/CHANGES +++ b/CHANGES @@ -87,7 +87,7 @@ CHANGES - Deferred column attributes no longer trigger a load operation when the attribute is assigned to. In those cases, the newly assigned value will be present in the flushes' UPDATE statement unconditionally. - + - Fixed a truncation error when re-assigning a subset of a collection (obj.relation = obj.relation[1:]) [ticket:834] diff --git a/lib/sqlalchemy/orm/sync.py b/lib/sqlalchemy/orm/sync.py index d858428611..5b5a9e43b1 100644 --- a/lib/sqlalchemy/orm/sync.py +++ b/lib/sqlalchemy/orm/sync.py @@ -118,7 +118,7 @@ class SyncRule(object): try: return self._dest_primary_key except AttributeError: - self._dest_primary_key = self.dest_mapper is not None and self.dest_column in self.dest_mapper.pks_by_table[self.dest_column.table] + self._dest_primary_key = self.dest_mapper is not None and self.dest_column in self.dest_mapper.pks_by_table[self.dest_column.table] and not self.dest_mapper.allow_null_pks return self._dest_primary_key def execute(self, source, dest, obj, child, clearkeys): diff --git a/test/orm/relationships.py b/test/orm/relationships.py index d21121e185..282d1cafc0 100644 --- a/test/orm/relationships.py +++ b/test/orm/relationships.py @@ -400,7 +400,40 @@ class RelationTest4(ORMTest): assert False except exceptions.AssertionError, e: assert str(e).startswith("Dependency rule tried to blank-out primary key column 'B.id' on instance ") + + def test_no_nullPK_sBtoA(self): + class A(object):pass + class B(object):pass + mapper(B, tableB, properties={ + 'a':relation(A, cascade="save-update") + }) + mapper(A, tableA) + b1 = B() + b1.a = None + sess = create_session() + sess.save(b1) + try: + # this raises an error as of r3695. in that rev, the attributes package was modified so that a + # setting of "None" shows up as a change, which in turn fires off dependency.py and then triggers + # the rule. + sess.flush() + assert False + except exceptions.AssertionError, e: + assert str(e).startswith("Dependency rule tried to blank-out primary key column 'B.id' on instance ") + def test_nullPKsOK_sBtoA(self): + class A(object):pass + class B(object):pass + mapper(B, tableB, properties={ + 'a':relation(A, cascade="save-update") + }, allow_null_pks=True) + mapper(A, tableA) + b1 = B() + b1.a = None + sess = create_session() + sess.save(b1) + sess.flush() + def test_delete_cascade_BtoA(self): """test that the 'blank the PK' error doesnt get raised when the child is to be deleted as part of a cascade"""