From 25b6e811e692d20495ea6bed93552a22a28f9d92 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 4 May 2012 19:27:52 -0400 Subject: [PATCH] - [bug] Fixed issue in unit of work whereby setting a non-None self-referential many-to-one relationship to None would fail to persist the change if the former value was not already loaded. [ticket:2477]. --- CHANGES | 7 +++++++ lib/sqlalchemy/orm/attributes.py | 2 +- test/orm/test_unitofworkv2.py | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index fde7c681d6..d29e6287ab 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,13 @@ CHANGES 0.7.7 ===== - orm + - [bug] Fixed issue in unit of work + whereby setting a non-None self-referential + many-to-one relationship to None + would fail to persist the change if the + former value was not already loaded. + [ticket:2477]. + - [feature] Added prefix_with() method to Query, calls upon select().prefix_with() to allow placement of MySQL SELECT diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 3b4f18b310..a7e1824a65 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -653,7 +653,7 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl): if current is not None: ret = [(instance_state(current), current)] else: - ret = [] + ret = [(None, None)] if self.key in state.committed_state: original = state.committed_state[self.key] diff --git a/test/orm/test_unitofworkv2.py b/test/orm/test_unitofworkv2.py index d7e2150db5..cfd36e696d 100644 --- a/test/orm/test_unitofworkv2.py +++ b/test/orm/test_unitofworkv2.py @@ -777,6 +777,31 @@ class SingleCycleTest(UOWTest): lambda ctx: {'id':n1.id}) ) + def test_many_to_one_set_null_unloaded(self): + Node, nodes = self.classes.Node, self.tables.nodes + + mapper(Node, nodes, properties={ + 'parent':relationship(Node, remote_side=nodes.c.id) + }) + sess = create_session() + n1 = Node(data='n1') + n2 = Node(data='n2', parent=n1) + sess.add_all([n1, n2]) + sess.flush() + sess.close() + + n2 = sess.query(Node).filter_by(data='n2').one() + n2.parent = None + self.assert_sql_execution( + testing.db, + sess.flush, + CompiledSQL( + "UPDATE nodes SET parent_id=:parent_id WHERE " + "nodes.id = :nodes_id", + lambda ctx: {"parent_id":None, "nodes_id":n2.id} + ) + ) + def test_cycle_rowswitch(self): Node, nodes = self.classes.Node, self.tables.nodes -- 2.47.2