From: Mike Bayer Date: Tue, 31 Mar 2009 14:57:19 +0000 (+0000) Subject: - Fixed another location where autoflush was interfering X-Git-Tag: rel_0_5_4~41 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=832ea82fefa366f4717e889511f66ecfce3313de;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixed another location where autoflush was interfering with session.merge(). autoflush is disabled completely for the duration of merge() now. [ticket:1360] --- diff --git a/CHANGES b/CHANGES index 172b2c23c6..ab264511c7 100644 --- 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 diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 8999e7d8ec..b9fe1c0f8a 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -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 diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index d8af4e74f5..954b313108 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -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() diff --git a/test/orm/merge.py b/test/orm/merge.py index ab56dd9783..b0e236ba2b 100644 --- a/test/orm/merge.py +++ b/test/orm/merge.py @@ -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()