]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- improved support for disabling save-update cascade via cascade="none" etc.
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 30 Nov 2006 00:08:46 +0000 (00:08 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 30 Nov 2006 00:08:46 +0000 (00:08 +0000)
CHANGES
lib/sqlalchemy/orm/unitofwork.py
test/orm/session.py

diff --git a/CHANGES b/CHANGES
index df487cf267b3593eb7eb2cf99d90dd571e1a2d3d..f5ea33a5d330bd38bb5298d41dac36b7dc499254 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,7 +9,7 @@ an instance is detected to be already in the session.
 - sending a selectable to an IN no longer creates a "union" out of multiple
 selects; only one selectable to an IN is allowed now (make a union yourself
 if union is needed; explicit better than implicit, dont guess, etc.)
-
+- improved support for disabling save-update cascade via cascade="none" etc.
 0.3.1
 - Engine/Pool:
   - some new Pool utility classes, updated docs
index a6f789e51a630df7614c1c79e542fe1eac7c61d8..4ecf8b4a046da47b6c61594d61e3e2f169f4de08 100644 (file)
@@ -101,7 +101,14 @@ class UnitOfWork(object):
         if (hasattr(obj, '_instance_key') and not self.identity_map.has_key(obj._instance_key)) or \
             (not hasattr(obj, '_instance_key') and obj not in self.new):
             raise InvalidRequestError("Instance '%s' is not attached or pending within this session" % repr(obj))
-
+    
+    def _is_valid(self, obj):
+        if (hasattr(obj, '_instance_key') and not self.identity_map.has_key(obj._instance_key)) or \
+            (not hasattr(obj, '_instance_key') and obj not in self.new):
+            return False
+        else:
+            return True
+        
     def register_attribute(self, class_, key, uselist, **kwargs):
         attribute_manager.register_attribute(class_, key, uselist, **kwargs)
 
@@ -219,9 +226,9 @@ class UOWTransaction(object):
         registration is entered for the object."""
         #print "REGISTER", repr(obj), repr(getattr(obj, '_instance_key', None)), str(isdelete), str(listonly)
         
-        # things can get really confusing if theres duplicate instances floating around,
-        # so make sure everything is OK
-        self.uow._validate_obj(obj)
+        # if object is not in the overall session, do nothing
+        if not self.uow._is_valid(obj):
+            return
             
         mapper = object_mapper(obj)
         self.mappers.add(mapper)
index 3f8adc3e9c0f0c75b0247c44e64c6e4cec680e13..5cb7009bb56bfae3e97cd9318e0d0e222aaa1f9b 100644 (file)
@@ -12,7 +12,6 @@ from sqlalchemy import *
 class SessionTest(AssertMixin):
     def setUpAll(self):
         tables.create()
-        tables.data()
     def tearDownAll(self):
         tables.drop()
     def tearDown(self):
@@ -93,6 +92,42 @@ class SessionTest(AssertMixin):
         assert user in s
         assert user not in s.dirty
         
+    def test_no_save_cascade(self):
+        mapper(Address, addresses)
+        mapper(User, users, properties=dict(
+            addresses=relation(Address, cascade="none", backref="user")
+        ))
+        s = create_session()
+        u = User()
+        s.save(u)
+        a = Address()
+        u.addresses.append(a)
+        assert u in s
+        assert a not in s
+        s.flush()
+        s.clear()
+        assert s.query(User).selectone().user_id == u.user_id
+        assert s.query(Address).selectfirst() is None
+        
+        clear_mappers()
+        
+        tables.delete()
+        mapper(Address, addresses)
+        mapper(User, users, properties=dict(
+            addresses=relation(Address, cascade="all", backref=backref("user", cascade="none"))
+        ))
+        
+        s = create_session()
+        u = User()
+        a = Address()
+        a.user = u
+        s.save(a)
+        assert u not in s
+        assert a in s
+        s.flush()
+        s.clear()
+        assert s.query(Address).selectone().address_id == a.address_id
+        assert s.query(User).selectfirst() is None
         
 class OrphanDeletionTest(AssertMixin):