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