From: Mike Bayer Date: Sun, 14 Oct 2007 18:01:37 +0000 (+0000) Subject: - backref remove object operation doesn't fail if the other-side X-Git-Tag: rel_0_3_11~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd941d126e19879319336f867f1a57ec40e30119;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - backref remove object operation doesn't fail if the other-side collection doesn't contain the item, supports noload collections [ticket:813] --- diff --git a/CHANGES b/CHANGES index 755f503de7..70c8753816 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,10 @@ no PK columns, would not detect that the joined table had no PK. - fixed bugs in determining proper sync clauses from custom inherit conditions [ticket:769] + - backref remove object operation doesn't fail if the other-side + collection doesn't contain the item, supports noload collections + [ticket:813] + - engine - fixed another occasional race condition which could occur when using pool with threadlocal setting diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 9f8a04db85..2348269388 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -643,7 +643,11 @@ class GenericBackrefExtension(AttributeExtension): if oldchild is child: return if oldchild is not None: - getattr(oldchild.__class__, self.key).remove(event, oldchild, obj) + try: + getattr(oldchild.__class__, self.key).remove(event, oldchild, obj) + except ValueError: + # supports 'noload' collections + pass if child is not None: getattr(child.__class__, self.key).append(event, child, obj) diff --git a/test/orm/unitofwork.py b/test/orm/unitofwork.py index 42bc4d1ad8..4bc6ff43e3 100644 --- a/test/orm/unitofwork.py +++ b/test/orm/unitofwork.py @@ -776,7 +776,7 @@ class OneToManyTest(UnitOfWorkTest): ctx.current.delete(u) ctx.current.flush() - + def testdoublerelation(self): m2 = mapper(Address, addresses) m = mapper(User, users, properties={ @@ -1154,6 +1154,31 @@ class ManyToOneTest(UnitOfWorkTest): u1 = ctx.current.query(User).get(u1.user_id) u2 = ctx.current.query(User).get(u2.user_id) assert a1.user is u2 + + def testbidirectional_noload(self): + mapper(User, users, properties={ + 'addresses':relation(Address, backref='user', lazy=None) + }) + mapper(Address, addresses) + + sess = ctx.current + + # try it on unsaved objects + u1 = User() + a1 = Address() + a1.user = u1 + sess.save(u1) + sess.flush() + sess.clear() + + a1 = sess.query(Address).get(a1.address_id) + + a1.user = None + sess.flush() + sess.clear() + assert sess.query(Address).get(a1.address_id).user is None + assert sess.query(User).get(u1.user_id).addresses == [] + class ManyToManyTest(UnitOfWorkTest): def setUpAll(self):