summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-10-14 18:06:13 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-10-14 18:06:13 +0000
commitb56ed8ccb84fb4e173930696ed052acdff5cc3ad (patch)
tree2fa476aca78bf83355d3b3bbd50ff7179d87330e
parentdda6a5f5a88a04d34b973cfb7c0f6d89d4b0e44f (diff)
downloadsqlalchemy-b56ed8ccb84fb4e173930696ed052acdff5cc3ad.tar.gz
- backref remove object operation doesn't fail if the other-side
collection doesn't contain the item, supports noload collections [ticket:813]
-rw-r--r--CHANGES4
-rw-r--r--lib/sqlalchemy/orm/attributes.py8
-rw-r--r--test/orm/unitofwork.py25
3 files changed, 36 insertions, 1 deletions
diff --git a/CHANGES b/CHANGES
index 53ce0e75e..7f1543e86 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,10 @@ CHANGES
- Added partial index support for PostgreSQL. Use the postgres_where keyword
on the Index.
+- backref remove object operation doesn't fail if the other-side
+ collection doesn't contain the item, supports noload collections
+ [ticket:813]
+
- The IdentifierPreprarer's _requires_quotes test is now regex based. Any
out-of-tree dialects that provide custom sets of legal_characters or
illegal_initial_characters will need to move to regexes or override
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py
index 714b00376..4b64d52e3 100644
--- a/lib/sqlalchemy/orm/attributes.py
+++ b/lib/sqlalchemy/orm/attributes.py
@@ -520,7 +520,13 @@ class GenericBackrefExtension(interfaces.AttributeExtension):
if oldchild is child:
return
if oldchild is not None:
- getattr(oldchild.__class__, self.key).impl.remove(oldchild._state, obj, initiator)
+ # With lazy=None, there's no guarantee that the full collection is
+ # present when updating via a backref.
+ impl = getattr(oldchild.__class__, self.key).impl
+ try:
+ impl.remove(oldchild._state, obj, initiator)
+ except (ValueError, KeyError, IndexError):
+ pass
if child is not None:
getattr(child.__class__, self.key).impl.append(child._state, obj, initiator)
diff --git a/test/orm/unitofwork.py b/test/orm/unitofwork.py
index dcf7581fe..d1011068b 100644
--- a/test/orm/unitofwork.py
+++ b/test/orm/unitofwork.py
@@ -1334,6 +1334,31 @@ class ManyToOneTest(ORMTest):
u1 = Session.query(User).get(u1.user_id)
u2 = Session.query(User).get(u2.user_id)
assert a1.user is u2
+
+ def test_bidirectional_noload(self):
+ mapper(User, users, properties={
+ 'addresses':relation(Address, backref='user', lazy=None)
+ })
+ mapper(Address, addresses)
+
+ sess = Session()
+
+ # 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(ORMTest):
metadata = tables.metadata