def fget(instance): dict_ = attributes.instance_dict(instance) if self.key not in dict_: # key not present. Iterate through related # attributes, retrieve their values. This # ensures they all load. values = [getattr(instance, key) for key in self._attribute_keys] # usually, the load() event will have loaded our key # at this point, unless we only loaded relationship() # attributes above. Populate here if that's the case. if self.key not in dict_ and not _none_set.issuperset(values): dict_[self.key] = self.composite_class(*values) return dict_.get(self.key, None)
def fget(instance): dict_ = attributes.instance_dict(instance) if self.key not in dict_: # key not present. Iterate through related # attributes, retrieve their values. This # ensures they all load. values = [ getattr(instance, key) for key in self._attribute_keys ] # usually, the load() event will have loaded our key # at this point, unless we only loaded relationship() # attributes above. Populate here if that's the case. if self.key not in dict_ and not _none_set.issuperset(values): dict_[self.key] = self.composite_class(*values) return dict_.get(self.key, None)
def fget(instance): dict_ = attributes.instance_dict(instance) state = attributes.instance_state(instance) if self.key not in dict_: # key not present. Iterate through related # attributes, retrieve their values. This # ensures they all load. values = [getattr(instance, key) for key in self._attribute_keys] # current expected behavior here is that the composite is # created on access if the object is persistent or if # col attributes have non-None. This would be better # if the composite were created unconditionally, # but that would be a behavioral change. if self.key not in dict_ and ( state.key is not None or not _none_set.issuperset(values) ): dict_[self.key] = self.composite_class(*values) state.manager.dispatch.refresh(state, None, [self.key]) return dict_.get(self.key, None)
def _load_for_state(self, state, passive): if not state.key and \ (not self.parent_property.load_on_pending or not state.session_id): return attributes.ATTR_EMPTY instance_mapper = state.manager.mapper prop = self.parent_property key = self.key prop_mapper = self.mapper pending = not state.key if ( (passive is attributes.PASSIVE_NO_FETCH or \ passive is attributes.PASSIVE_NO_FETCH_RELATED) and not self.use_get ) or ( passive is attributes.PASSIVE_ONLY_PERSISTENT and pending ): return attributes.PASSIVE_NO_RESULT session = sessionlib._state_session(state) if not session: raise orm_exc.DetachedInstanceError( "Parent instance %s is not bound to a Session; " "lazy load operation of attribute '%s' cannot proceed" % (mapperutil.state_str(state), key)) # if we have a simple primary key load, check the # identity map without generating a Query at all if self.use_get: if session._flushing: get_attr = instance_mapper._get_committed_state_attr_by_column else: get_attr = instance_mapper._get_state_attr_by_column dict_ = state.dict if passive is attributes.PASSIVE_NO_FETCH_RELATED: attr_passive = attributes.PASSIVE_OFF else: attr_passive = passive ident = [ get_attr(state, state.dict, self._equated_columns[pk], passive=attr_passive) for pk in prop_mapper.primary_key ] if attributes.PASSIVE_NO_RESULT in ident: return attributes.PASSIVE_NO_RESULT if _none_set.issuperset(ident): return None ident_key = prop_mapper.identity_key_from_primary_key(ident) instance = Query._get_from_identity(session, ident_key, passive) if instance is not None: return instance elif passive is attributes.PASSIVE_NO_FETCH or \ passive is attributes.PASSIVE_NO_FETCH_RELATED: return attributes.PASSIVE_NO_RESULT q = session.query(prop_mapper)._adapt_all_clauses() # don't autoflush on pending if pending: q = q.autoflush(False) if state.load_path: q = q._with_current_path(state.load_path + (key, )) if state.load_options: q = q._conditional_options(*state.load_options) if self.use_get: return q._load_on_ident(ident_key) if prop.order_by: q = q.order_by(*util.to_list(prop.order_by)) for rev in prop._reverse_property: # reverse props that are MANYTOONE are loading *this* # object from get(), so don't need to eager out to those. if rev.direction is interfaces.MANYTOONE and \ rev._use_get and \ not isinstance(rev.strategy, LazyLoader): q = q.options(EagerLazyOption((rev.key, ), lazy='select')) lazy_clause = self.lazy_clause(state) if pending: bind_values = sql_util.bind_values(lazy_clause) if None in bind_values: return None q = q.filter(lazy_clause) result = q.all() if self.uselist: return result else: l = len(result) if l: if l > 1: util.warn( "Multiple rows returned with " "uselist=False for lazily-loaded attribute '%s' " % prop) return result[0] else: return None
def _load_for_state(self, state, passive): if not state.key and \ (not self.parent_property.load_on_pending or not state.session_id): return attributes.ATTR_EMPTY instance_mapper = state.manager.mapper prop = self.parent_property key = self.key prop_mapper = self.mapper pending = not state.key if ( (passive is attributes.PASSIVE_NO_FETCH or \ passive is attributes.PASSIVE_NO_FETCH_RELATED) and not self.use_get ) or ( passive is attributes.PASSIVE_ONLY_PERSISTENT and pending ): return attributes.PASSIVE_NO_RESULT session = sessionlib._state_session(state) if not session: raise orm_exc.DetachedInstanceError( "Parent instance %s is not bound to a Session; " "lazy load operation of attribute '%s' cannot proceed" % (mapperutil.state_str(state), key) ) # if we have a simple primary key load, check the # identity map without generating a Query at all if self.use_get: if session._flushing: get_attr = instance_mapper._get_committed_state_attr_by_column else: get_attr = instance_mapper._get_state_attr_by_column dict_ = state.dict if passive is attributes.PASSIVE_NO_FETCH_RELATED: attr_passive = attributes.PASSIVE_OFF else: attr_passive = passive ident = [ get_attr( state, state.dict, self._equated_columns[pk], passive=attr_passive) for pk in prop_mapper.primary_key ] if attributes.PASSIVE_NO_RESULT in ident: return attributes.PASSIVE_NO_RESULT if _none_set.issuperset(ident): return None ident_key = prop_mapper.identity_key_from_primary_key(ident) instance = Query._get_from_identity(session, ident_key, passive) if instance is not None: return instance elif passive is attributes.PASSIVE_NO_FETCH or \ passive is attributes.PASSIVE_NO_FETCH_RELATED: return attributes.PASSIVE_NO_RESULT q = session.query(prop_mapper)._adapt_all_clauses() # don't autoflush on pending if pending: q = q.autoflush(False) if state.load_path: q = q._with_current_path(state.load_path + (key,)) if state.load_options: q = q._conditional_options(*state.load_options) if self.use_get: return q._load_on_ident(ident_key) if prop.order_by: q = q.order_by(*util.to_list(prop.order_by)) for rev in prop._reverse_property: # reverse props that are MANYTOONE are loading *this* # object from get(), so don't need to eager out to those. if rev.direction is interfaces.MANYTOONE and \ rev._use_get and \ not isinstance(rev.strategy, LazyLoader): q = q.options(EagerLazyOption((rev.key,), lazy='select')) lazy_clause = self.lazy_clause(state) if pending: bind_values = sql_util.bind_values(lazy_clause) if None in bind_values: return None q = q.filter(lazy_clause) result = q.all() if self.uselist: return result else: l = len(result) if l: if l > 1: util.warn( "Multiple rows returned with " "uselist=False for lazily-loaded attribute '%s' " % prop) return result[0] else: return None