summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-01-21 20:08:56 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-01-21 20:08:56 -0500
commit560fd1d5ed643a1b0f95296f3b840c1963bbe67f (patch)
tree234ed5969b06bbb071d2e1a692ba5a7fe53c4dcb
parent23a5bacf060b838628720fe419aef4f5aa348b8a (diff)
downloadsqlalchemy-560fd1d5ed643a1b0f95296f3b840c1963bbe67f.tar.gz
handle the case where we want to delete/insert on PK, disable row switch
-rw-r--r--lib/sqlalchemy/orm/dependency.py10
-rw-r--r--lib/sqlalchemy/orm/persistence.py24
-rw-r--r--lib/sqlalchemy/orm/unitofwork.py1
3 files changed, 23 insertions, 12 deletions
diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py
index 12676faca..9f1e497af 100644
--- a/lib/sqlalchemy/orm/dependency.py
+++ b/lib/sqlalchemy/orm/dependency.py
@@ -1215,6 +1215,16 @@ class DeleteBeforeInsertDP(object):
(before_delete, deletes)
])
+ @classmethod
+ def save_depends_on_delete(cls, uow, dependent, dependee, mapper):
+ """return True if we've set up a dependency rule between two
+ states.
+
+ """
+ dep_proc = unitofwork.SaveUpdateState(uow, dependent, mapper)
+ dee_proc = unitofwork.DeleteState(uow, dependee, mapper)
+ return (dee_proc, dep_proc) in uow.dependencies
+
def per_state_flush_actions(self, uow, states, isdelete):
# finally, we get called when the UOW has decided, "OK,
# we need to figure out on a state-by-state basis which of you
diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py
index 44da88118..1f5507edf 100644
--- a/lib/sqlalchemy/orm/persistence.py
+++ b/lib/sqlalchemy/orm/persistence.py
@@ -119,8 +119,8 @@ def delete_obj(base_mapper, states, uowtransaction):
in states_to_delete:
mapper.dispatch.after_delete(mapper, connection, state)
-
-def _organize_states_for_save(base_mapper, states, uowtransaction):
+@util.dependencies("sqlalchemy.orm.dependency")
+def _organize_states_for_save(dependency, base_mapper, states, uowtransaction):
"""Make an initial pass across a set of states for INSERT or
UPDATE.
@@ -168,16 +168,16 @@ def _organize_states_for_save(base_mapper, states, uowtransaction):
"with persistent instance %s" %
(state_str(state), instance_key,
state_str(existing)))
-
- base_mapper._log_debug(
- "detected row switch for identity %s. "
- "will update %s, remove %s from "
- "transaction", instance_key,
- state_str(state), state_str(existing))
-
- # remove the "delete" flag from the existing element
- uowtransaction.remove_state_actions(existing)
- row_switch = existing
+ elif not dependency.DeleteBeforeInsertDP.save_depends_on_delete(uowtransaction, state, existing, mapper):
+ base_mapper._log_debug(
+ "detected row switch for identity %s. "
+ "will update %s, remove %s from "
+ "transaction", instance_key,
+ state_str(state), state_str(existing))
+
+ # remove the "delete" flag from the existing element
+ uowtransaction.remove_state_actions(existing)
+ row_switch = existing
if not has_identity and not row_switch:
states_to_insert.append(
diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py
index f2a419733..1e8d3e4dc 100644
--- a/lib/sqlalchemy/orm/unitofwork.py
+++ b/lib/sqlalchemy/orm/unitofwork.py
@@ -160,6 +160,7 @@ class UOWTransaction(object):
return state in self.states and self.states[state][0]
+
def memo(self, key, callable_):
if key in self.attributes:
return self.attributes[key]