summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-01-18 16:34:34 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2011-01-18 16:34:34 -0500
commitb3dd50a8dac9f7660b7f497f444e6175fdf85713 (patch)
tree49d6da2e2018092b273734df79bfd501cd4e4579 /lib/sqlalchemy
parent0f52225ba8a10500eff2b5671ca737479ff59bff (diff)
downloadsqlalchemy-b3dd50a8dac9f7660b7f497f444e6175fdf85713.tar.gz
- 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]
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/session.py28
1 files changed, 28 insertions, 0 deletions
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