def _load_for_state(self, state, passive): if not state.key: return attributes.ATTR_EMPTY if passive is attributes.PASSIVE_NO_FETCH: return attributes.PASSIVE_NO_RESULT prop = self.parent_property localparent = state.manager.mapper if self.group: toload = [ p.key for p in localparent.iterate_properties if isinstance(p, StrategizedProperty) and isinstance( p.strategy, DeferredColumnLoader) and p.group == self.group ] else: toload = [self.key] # narrow the keys down to just those which have no history group = [k for k in toload if k in state.unmodified] session = sessionlib._state_session(state) if session is None: raise orm_exc.DetachedInstanceError( "Parent instance %s is not bound to a Session; " "deferred load operation of attribute '%s' cannot proceed" % (mapperutil.state_str(state), self.key)) query = session.query(localparent) query._load_on_ident(state.key, only_load_props=group, refresh_state=state) return attributes.ATTR_WAS_SET
def __call__(self, **kw): if kw.get('passive') is attributes.PASSIVE_NO_FETCH: return attributes.PASSIVE_NO_RESULT state = self.state localparent = mapper._state_mapper(state) prop = localparent.get_property(self.key) strategy = prop._get_strategy(DeferredColumnLoader) if strategy.group: toload = [ p.key for p in localparent.iterate_properties if isinstance(p, StrategizedProperty) and isinstance(p.strategy, DeferredColumnLoader) and p.group == strategy.group ] else: toload = [self.key] # narrow the keys down to just those which have no history group = [k for k in toload if k in state.unmodified] if strategy._should_log_debug(): strategy.logger.debug( "deferred load %s group %s", (mapperutil.state_attribute_str( state, self.key), group and ','.join(group) or 'None')) session = sessionlib._state_session(state) if session is None: raise orm_exc.DetachedInstanceError( "Parent instance %s is not bound to a Session; " "deferred load operation of attribute '%s' cannot proceed" % (mapperutil.state_str(state), self.key)) query = session.query(localparent) ident = state.key[1] query._get(None, ident=ident, only_load_props=group, refresh_state=state) return attributes.ATTR_WAS_SET
def _clone(self, sess=None): # note we're returning an entirely new Query class instance # here without any assignment capabilities; the class of this # query is determined by the session. instance = self.instance if sess is None: sess = object_session(instance) if sess is None: raise orm_exc.DetachedInstanceError( "Parent instance %s is not bound to a Session, and no " "contextual session is established; lazy load operation " "of attribute '%s' cannot proceed" % (mapperutil.instance_str(instance), self.attr.key)) if self.query_class: query = self.query_class(self.attr.target_mapper, session=sess) else: query = sess.query(self.attr.target_mapper) query._criterion = self._criterion query._order_by = self._order_by return query
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 __call__(self, **kw): state = self.state instance_mapper = mapper._state_mapper(state) prop = instance_mapper.get_property(self.key) strategy = prop._get_strategy(LazyLoader) if kw.get('passive') is attributes.PASSIVE_NO_FETCH and \ not strategy.use_get: return attributes.PASSIVE_NO_RESULT if strategy._should_log_debug(): strategy.logger.debug( "loading %s", mapperutil.state_attribute_str(state, self.key)) session = sessionlib._state_session(state) if session is None: 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), self.key)) q = session.query(prop.mapper)._adapt_all_clauses() if state.load_path: q = q._with_current_path(state.load_path + (self.key, )) # if we have a simple primary key load, use mapper.get() # to possibly save a DB round trip if strategy.use_get: ident = [] allnulls = True for primary_key in prop.mapper.primary_key: val = instance_mapper.\ _get_committed_state_attr_by_column( state, state.dict, strategy._equated_columns[primary_key], **kw) if val is attributes.PASSIVE_NO_RESULT: return val allnulls = allnulls and val is None ident.append(val) if allnulls: return None if state.load_options: q = q._conditional_options(*state.load_options) key = prop.mapper.identity_key_from_primary_key(ident) return q._get(key, ident, **kw) 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')) if state.load_options: q = q._conditional_options(*state.load_options) q = q.filter(strategy.lazy_clause(state)) result = q.all() if strategy.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