]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
moved the non-expire of unloaded deferred attributes into the attributes package
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 24 Jan 2009 15:43:05 +0000 (15:43 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 24 Jan 2009 15:43:05 +0000 (15:43 +0000)
lib/sqlalchemy/orm/attributes.py
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/session.py
lib/sqlalchemy/orm/strategies.py

index 70b0738c955399fa0a10ddd060de0065b154f282..729ab12772838394ec17321e497c42877518c94f 100644 (file)
@@ -160,7 +160,8 @@ class InstrumentedAttribute(QueryableAttribute):
 
 class _ProxyImpl(object):
     accepts_scalar_loader = False
-
+    dont_expire_missing = False
+    
     def __init__(self, key):
         self.key = key
 
@@ -230,7 +231,9 @@ class AttributeImpl(object):
 
     def __init__(self, class_, key,
                     callable_, trackparent=False, extension=None,
-                    compare_function=None, active_history=False, parent_token=None, **kwargs):
+                    compare_function=None, active_history=False, parent_token=None, 
+                    dont_expire_missing=False,
+                    **kwargs):
         """Construct an AttributeImpl.
 
         \class_
@@ -268,6 +271,11 @@ class AttributeImpl(object):
           Allows multiple AttributeImpls to all match a single 
           owner attribute.
           
+        dont_expire_missing
+          if True, don't add an "expiry" callable to this attribute
+          during state.expire_attributes(None), if no value is present 
+          for this key.
+          
         """
         self.class_ = class_
         self.key = key
@@ -280,7 +288,8 @@ class AttributeImpl(object):
             self.is_equal = compare_function
         self.extensions = util.to_list(extension or [])
         self.active_history = active_history
-
+        self.dont_expire_missing = dont_expire_missing
+        
     def hasparent(self, state, optimistic=False):
         """Return the boolean value of a `hasparent` flag attached to the given item.
 
@@ -1006,12 +1015,19 @@ class InstanceState(object):
             attribute_names = self.manager.keys()
             self.expired = True
             self.modified = False
+            filter_deferred = True
+        else:
+            filter_deferred = False
         for key in attribute_names:
+            impl = self.manager[key].impl
+            if not filter_deferred or \
+                not impl.dont_expire_missing or \
+                key in self.dict:
+                self.expired_attributes.add(key)
+                if impl.accepts_scalar_loader:
+                    self.callables[key] = self
             self.dict.pop(key, None)
             self.committed_state.pop(key, None)
-            self.expired_attributes.add(key)
-            if self.manager.get_impl(key).accepts_scalar_loader:
-                self.callables[key] = self
 
     def reset(self, key):
         """remove the given attribute and any callables associated with it."""
index 6f125bc8413116d6e36449039fad5b222ba50ce6..1cd8e055b013e2fcdd911871403c862182601188 100644 (file)
@@ -776,11 +776,6 @@ class Mapper(object):
             raise sa_exc.InvalidRequestError("Mapper '%s' has no property '%s'" % (str(self), key))
         return prop
     
-    @util.memoized_property
-    def _deferred_props(self):
-        return [p.key for p in self._props.values() if 
-                isinstance(p, ColumnProperty) and getattr(p, 'deferred', False)]
-        
     @property
     def iterate_properties(self):
         """return an iterator of all MapperProperty objects."""
index ea8174726ac7b2f674b7086bd7b1884e7caff2b3..4fb6c185934af8247c42c50b745768631beec796 100644 (file)
@@ -1518,14 +1518,7 @@ class Session(object):
 
         return util.IdentitySet(self._new.values())
 
-def _expire_state(state, attribute_names):
-    if attribute_names is None:
-        state.expired = True
-        state.modified= False
-        # dont add unloaded deferred attributes to the list of attrs
-        attribute_names = set(state.manager.keys()).\
-                difference([k for k in state.manager.mapper._deferred_props if k not in state.dict])
-    state.expire_attributes(attribute_names)
+_expire_state = attributes.InstanceState.expire_attributes
     
 UOWEventHandler = unitofwork.UOWEventHandler
 
index 2a78c90de92836ae53f8eabbc9b05beb2af4679f..91b2f359a93b80bf537f2f07ad38a34eb99dca0b 100644 (file)
@@ -228,6 +228,7 @@ class DeferredColumnLoader(LoaderStrategy):
              copy_function=self.columns[0].type.copy_value,
              mutable_scalars=self.columns[0].type.is_mutable(),
              callable_=self.class_level_loader,
+             dont_expire_missing=True
         )
 
     def setup_query(self, context, entity, path, adapter, only_load_props=None, **kwargs):