From b3dd50a8dac9f7660b7f497f444e6175fdf85713 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 18 Jan 2011 16:34:34 -0500 Subject: - Session.merge() will check the version id of the incoming state against that of the database, assuming the mapping uses version ids and incoming state has a version_id assigned, and raise StaleDataError if they don't match. [ticket:2027] --- lib/sqlalchemy/orm/session.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 47420e207..0e1818241 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -1242,6 +1242,34 @@ class Session(object): # check that we didn't just pull the exact same # state out. if state is not merged_state: + # version check if applicable + if mapper.version_id_col is not None: + existing_version = mapper._get_state_attr_by_column( + state, + state_dict, + mapper.version_id_col, + passive=attributes.PASSIVE_NO_INITIALIZE) + + merged_version = mapper._get_state_attr_by_column( + merged_state, + merged_dict, + mapper.version_id_col, + passive=attributes.PASSIVE_NO_INITIALIZE) + + if existing_version is not attributes.PASSIVE_NO_RESULT and \ + merged_version is not attributes.PASSIVE_NO_RESULT and \ + existing_version != merged_version: + raise exc.StaleDataError( + "Version id '%s' on merged state %s " + "does not match existing version '%s'. " + "Leave the version attribute unset when " + "merging to update the most recent version." + % ( + existing_version, + mapperutil.state_str(merged_state), + merged_version + )) + merged_state.load_path = state.load_path merged_state.load_options = state.load_options -- cgit v1.2.1