From: Mike Bayer Date: Mon, 14 Dec 2009 01:34:06 +0000 (+0000) Subject: - merged r6553 from trunk X-Git-Tag: rel_0_5_7~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cd464c7aac765f65c032cf1f6a6a59010b7f1607;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - merged r6553 from trunk - Session.merge() now properly overwrites a many-to-one or uselist=False attribute to None if the attribute is also None in the given object to be merged. --- diff --git a/CHANGES b/CHANGES index 3cee14b5af..e804822c37 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,10 @@ CHANGES in expression which is an insert()/update()/delete() construct. [ticket:1054] + - Session.merge() now properly overwrites a many-to-one or + uselist=False attribute to None if the attribute + is also None in the given object to be merged. + - Fixed a needless select which would occur when merging transient objects that contained a null primary key identifier. [ticket:1618] diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index e874e37471..e3ecad3b10 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -665,11 +665,13 @@ class RelationProperty(StrategizedProperty): if current is not None: _recursive[(current, self)] = True obj = session._merge(current, dont_load=dont_load, _recursive=_recursive) - if obj is not None: - if dont_load: - dest_state.dict[self.key] = obj - else: - setattr(dest, self.key, obj) + else: + obj = None + + if dont_load: + dest_state.dict[self.key] = obj + else: + setattr(dest, self.key, obj) def cascade_iterator(self, type_, state, visited_instances, halt_on=None): if not type_ in self.cascade: diff --git a/test/orm/test_merge.py b/test/orm/test_merge.py index d0f667237c..4c8fb87839 100644 --- a/test/orm/test_merge.py +++ b/test/orm/test_merge.py @@ -454,6 +454,28 @@ class MergeTest(_fixtures.FixtureTest): eq_(on_load.called, 2) assert u3 is u + @testing.resolve_artifact_names + def test_value_to_none(self): + mapper(User, users, properties={ + 'address':relation(mapper(Address, addresses),uselist = False, backref='user') + }) + sess = sessionmaker()() + u = User(id=7, name="fred", address=Address(id=1, email_address='foo@bar.com')) + sess.add(u) + sess.commit() + sess.close() + + u2 = User(id=7, name=None, address=None) + u3 = sess.merge(u2) + assert u3.name is None + assert u3.address is None + + sess.close() + + a1 = Address(id=1, user=None) + a2 = sess.merge(a1) + assert a2.user is None + @testing.resolve_artifact_names def test_transient_dontload(self): mapper(User, users)