From 24ee97c6100988a2ef80bd18d70418eb76070e4d Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 24 Aug 2008 21:52:38 +0000 Subject: - Fixed bug whereby changing a primary key attribute on an entity where the attribute's previous value had been expired would produce an error upon flush(). [ticket:1151] --- lib/sqlalchemy/orm/attributes.py | 15 ++++++++++----- lib/sqlalchemy/orm/session.py | 4 ++-- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 6fd134242..88e124e4b 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -217,12 +217,17 @@ class AttributeImpl(object): to it via this attribute. extension - an AttributeExtension object which will receive - set/delete/append/remove/etc. events. + a single or list of AttributeExtension object(s) which will + receive set/delete/append/remove/etc. events. compare_function a function that compares two values which are normally assignable to this attribute. + + active_history + indicates that get_history() should always return the "old" value, + even if it means executing a lazy callable upon attribute change. + This flag is set to True if any extensions are present. """ @@ -231,12 +236,12 @@ class AttributeImpl(object): self.callable_ = callable_ self.class_manager = class_manager self.trackparent = trackparent - self.active_history = active_history if compare_function is None: self.is_equal = operator.eq else: self.is_equal = compare_function self.extensions = util.to_list(extension or []) + self.active_history = active_history or bool(self.extensions) def hasparent(self, state, optimistic=False): """Return the boolean value of a `hasparent` flag attached to the given item. @@ -367,7 +372,7 @@ class ScalarAttributeImpl(AttributeImpl): def delete(self, state): # TODO: catch key errors, convert to attributeerror? - if self.active_history or self.extensions: + if self.active_history: old = self.get(state) else: old = state.dict.get(self.key, NO_VALUE) @@ -388,7 +393,7 @@ class ScalarAttributeImpl(AttributeImpl): if initiator is self: return - if self.active_history or self.extensions: + if self.active_history: old = self.get(state) else: old = state.dict.get(self.key, NO_VALUE) diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 20bb85e80..b46ae16d3 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -1220,15 +1220,15 @@ class Session(object): merged_state._run_on_load(merged) return merged + @classmethod def identity_key(cls, *args, **kwargs): return mapperutil.identity_key(*args, **kwargs) - identity_key = classmethod(identity_key) + @classmethod def object_session(cls, instance): """Return the ``Session`` to which an object belongs.""" return object_session(instance) - object_session = classmethod(object_session) def _validate_persistent(self, state): if not self.identity_map.contains_state(state): -- cgit v1.2.1