summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2009-03-31 14:57:19 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2009-03-31 14:57:19 +0000
commit832ea82fefa366f4717e889511f66ecfce3313de (patch)
tree0edb6b2ea2f3b4fd8580c48af93286a8806f11da
parentaca84bebb091a51ceeb911249c366e17b954826a (diff)
downloadsqlalchemy-832ea82fefa366f4717e889511f66ecfce3313de.tar.gz
- Fixed another location where autoflush was interfering
with session.merge(). autoflush is disabled completely for the duration of merge() now. [ticket:1360]
-rw-r--r--CHANGES4
-rw-r--r--lib/sqlalchemy/orm/properties.py4
-rw-r--r--lib/sqlalchemy/orm/session.py25
-rw-r--r--test/orm/merge.py29
4 files changed, 50 insertions, 12 deletions
diff --git a/CHANGES b/CHANGES
index 172b2c23c..ab264511c 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 8999e7d8e..b9fe1c0f8 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 d8af4e74f..954b31310 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 ab56dd978..b0e236ba2 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()