class _ProxyImpl(object):
accepts_scalar_loader = False
-
+ dont_expire_missing = False
+
def __init__(self, key):
self.key = key
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_
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
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.
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."""
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."""
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
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):