From 6698e1ab449042f56a1c1db98043d77a62f8ef08 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 27 Mar 2006 02:02:06 +0000 Subject: [PATCH] backrefs on cyclical relationships were breaking for the "root" node which had None for a parent, due to addition in [changeset:1186] which added a "deletion" traversal for many-to-one relationships. added unittest. --- lib/sqlalchemy/mapping/properties.py | 3 +++ lib/sqlalchemy/mapping/unitofwork.py | 4 ++++ test/cycles.py | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/lib/sqlalchemy/mapping/properties.py b/lib/sqlalchemy/mapping/properties.py index 10d6472f4c..b18d4d54fe 100644 --- a/lib/sqlalchemy/mapping/properties.py +++ b/lib/sqlalchemy/mapping/properties.py @@ -382,6 +382,9 @@ class PropertyLoader(MapperProperty): else: uowcommit.register_dependency(self.mapper, self.parent) uowcommit.register_processor(self.mapper, self, self.parent, False) + # this dependency processor is used to locate "private" child objects + # during a "delete" operation, when the objectstore is being committed + # with only a partial list of objects uowcommit.register_processor(self.mapper, self, self.parent, True) else: raise AssertionError(" no foreign key ?") diff --git a/lib/sqlalchemy/mapping/unitofwork.py b/lib/sqlalchemy/mapping/unitofwork.py index 0b392b4470..1eea546df7 100644 --- a/lib/sqlalchemy/mapping/unitofwork.py +++ b/lib/sqlalchemy/mapping/unitofwork.py @@ -647,6 +647,10 @@ class UOWTask(object): childlist = childlist.added_items() for o in childlist: + if o is None: + # this can be None due to the many-to-one dependency processor added + # for deleted items, line 385 properties.py + continue if not o in childtask.objects: # item needs to be saved since its added, or attached to a deleted object childtask.append(o, isdelete=isdelete and dep.processor.private) diff --git a/test/cycles.py b/test/cycles.py index 9114eb4fe0..02d34bbb0c 100644 --- a/test/cycles.py +++ b/test/cycles.py @@ -44,6 +44,19 @@ class SelfReferentialTest(AssertMixin): objectstore.clear() clear_mappers() + def testsingle(self): + class C1(Tester): + pass + m1 = mapper(C1, t1, properties = { + 'c1s':relation(C1, private=True), + 'parent':relation(C1, primaryjoin=t1.c.parent_c1==t1.c.c1, foreignkey=t1.c.c1, lazy=True, uselist=False) + }) + a = C1('head c1') + a.c1s.append(C1('another c1')) + objectstore.commit() + objectstore.delete(a) + objectstore.commit() + def testcycle(self): class C1(Tester): pass -- 2.47.2