diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-01-21 20:08:56 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-01-21 20:08:56 -0500 |
commit | 560fd1d5ed643a1b0f95296f3b840c1963bbe67f (patch) | |
tree | 234ed5969b06bbb071d2e1a692ba5a7fe53c4dcb | |
parent | 23a5bacf060b838628720fe419aef4f5aa348b8a (diff) | |
download | sqlalchemy-560fd1d5ed643a1b0f95296f3b840c1963bbe67f.tar.gz |
handle the case where we want to delete/insert on PK, disable row switch
-rw-r--r-- | lib/sqlalchemy/orm/dependency.py | 10 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/persistence.py | 24 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/unitofwork.py | 1 |
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] |