]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed another location where autoflush was interfering
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 31 Mar 2009 14:57:19 +0000 (14:57 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 31 Mar 2009 14:57:19 +0000 (14:57 +0000)
with session.merge().  autoflush is disabled completely
for the duration of merge() now. [ticket:1360]

CHANGES
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/orm/session.py
test/orm/merge.py

diff --git a/CHANGES b/CHANGES
index 172b2c23c64bfa072f293a21b8c290073331491f..ab264511c7e2ab53e6b2fd31a6e7692d58eef8b8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -21,6 +21,10 @@ CHANGES
       parameters but this would require further development.
       [ticket:1357]
 
+    - Fixed another location where autoflush was interfering
+      with session.merge().  autoflush is disabled completely
+      for the duration of merge() now. [ticket:1360]
+      
 - sql
     - ``sqlalchemy.extract()`` is now dialect sensitive and can
       extract components of timestamps idiomatically across the
index 8999e7d8ece151b4c53b31c9d862490735669b53..b9fe1c0f8ad986fb3e21720c34c4da7aaf5a2ff2 100644 (file)
@@ -650,7 +650,7 @@ class RelationProperty(StrategizedProperty):
             dest_list = []
             for current in instances:
                 _recursive[(current, self)] = True
-                obj = session.merge(current, dont_load=dont_load, _recursive=_recursive)
+                obj = session._merge(current, dont_load=dont_load, _recursive=_recursive)
                 if obj is not None:
                     dest_list.append(obj)
             if dont_load:
@@ -663,7 +663,7 @@ class RelationProperty(StrategizedProperty):
             current = instances[0]
             if current is not None:
                 _recursive[(current, self)] = True
-                obj = session.merge(current, dont_load=dont_load, _recursive=_recursive)
+                obj = session._merge(current, dont_load=dont_load, _recursive=_recursive)
                 if obj is not None:
                     if dont_load:
                         dest_state.dict[self.key] = obj
index d8af4e74f5a548adc380f323ce12242bbb0bc7cc..954b313108aa5e69737ea0d423ea7b840894f91e 100644 (file)
@@ -1141,8 +1141,7 @@ class Session(object):
         for state, m, o in cascade_states:
             self._delete_impl(state)
 
-    def merge(self, instance, dont_load=False,
-              _recursive=None):
+    def merge(self, instance, dont_load=False):
         """Copy the state an instance onto the persistent instance with the same identifier.
 
         If there is no persistent instance currently associated with the
@@ -1155,13 +1154,18 @@ class Session(object):
         mapped with ``cascade="merge"``.
 
         """
-        if _recursive is None:
-            # TODO: this should be an IdentityDict for instances, but will
-            # need a separate dict for PropertyLoader tuples
-            _recursive = {}
-            # Autoflush only on the topmost call
-            self._autoflush()
-
+        # TODO: this should be an IdentityDict for instances, but will
+        # need a separate dict for PropertyLoader tuples
+        _recursive = {}
+        self._autoflush()
+        autoflush = self.autoflush
+        try:
+            self.autoflush = False
+            return self._merge(instance, dont_load=dont_load, _recursive=_recursive)
+        finally:
+            self.autoflush = autoflush
+        
+    def _merge(self, instance, dont_load=False, _recursive=None):
         mapper = _object_mapper(instance)
         if instance in _recursive:
             return _recursive[instance]
@@ -1169,6 +1173,7 @@ class Session(object):
         new_instance = False
         state = attributes.instance_state(instance)
         key = state.key
+
         if key is None:
             if dont_load:
                 raise sa_exc.InvalidRequestError(
@@ -1194,7 +1199,7 @@ class Session(object):
                 self._update_impl(merged_state)
                 new_instance = True
             else:
-                merged = self.query(mapper.class_).autoflush(False).get(key[1])
+                merged = self.query(mapper.class_).get(key[1])
 
         if merged is None:
             merged = mapper.class_manager.new_instance()
index ab56dd9783811f7caf5793b7ecca59985b77b005..b0e236ba2bcd4768aa37b1654fbcd64edbf2d214 100644 (file)
@@ -694,5 +694,34 @@ class MergeTest(_fixtures.FixtureTest):
         sess.flush()
         assert merged_user not in sess.new
 
+    @testing.resolve_artifact_names
+    def test_cascades_dont_autoflush_2(self):
+        mapper(User, users, properties={
+            'addresses':relation(Address,
+                        backref='user',
+                                 cascade="all, delete-orphan")
+        })
+        mapper(Address, addresses)
+
+        u = User(id=7, name='fred', addresses=[
+            Address(id=1, email_address='fred1'),
+        ])
+        sess = create_session(autoflush=True, autocommit=False)
+        sess.add(u)
+        sess.commit()
+
+        sess.expunge_all()
+
+        u = User(id=7, name='fred', addresses=[
+            Address(id=1, email_address='fred1'),
+            Address(id=2, email_address='fred2'),
+        ])
+        sess.merge(u)
+        assert sess.autoflush
+        sess.commit()
+
+
+
+
 if __name__ == "__main__":
     testenv.main()