def execute(instance, row, isnew, **flags): decorated_row = row_decorator(row) if not self.uselist: if self._should_log_debug: self.logger.debug("eagerload scalar instance on %s" % mapperutil.attribute_str(instance, self.key)) if isnew: # set a scalar object instance directly on the # parent object, bypassing InstrumentedAttribute # event handlers. # instance.__dict__[self.key] = self.mapper._instance(selectcontext, decorated_row, None) else: # call _instance on the row, even though the object has been created, # so that we further descend into properties self.mapper._instance(selectcontext, decorated_row, None) else: if isnew or self.key not in instance._state.appenders: # appender_key can be absent from selectcontext.attributes with isnew=False # when self-referential eager loading is used; the same instance may be present # in two distinct sets of result columns if self._should_log_debug: self.logger.debug("initialize UniqueAppender on %s" % mapperutil.attribute_str(instance, self.key)) collection = attributes.init_collection(instance, self.key) appender = util.UniqueAppender(collection, 'append_without_event') instance._state.appenders[self.key] = appender result_list = instance._state.appenders[self.key] if self._should_log_debug: self.logger.debug("eagerload list instance on %s" % mapperutil.attribute_str(instance, self.key)) self.mapper._instance(selectcontext, decorated_row, result_list)
def new_execute(state, dict_, row): collection = attributes.init_state_collection( state, dict_, key) result_list = util.UniqueAppender(collection, 'append_without_event') context.attributes[(state, key)] = result_list _instance(row, result_list)
def load_collection_from_nested_new_row(state, dict_, row): collection = attributes.init_state_collection(state, dict_, key) result_list = util.UniqueAppender(collection, 'append_without_event') context.attributes[(state, key)] = result_list for nested_row in row[our_col]: _instance(nested_row, result_list)
def execute(instance, row, isnew, **flags): decorated_row = row_decorator(row) selectcontext.stack.push_property(self.key) if not self.uselist: if self._should_log_debug: self.logger.debug( "eagerload scalar instance on %s" % mapperutil.attribute_str(instance, self.key)) if isnew: # set a scalar object instance directly on the # parent object, bypassing InstrumentedAttribute # event handlers. # # FIXME: instead of... sessionlib.attribute_manager.set_raw_value( instance, self.key, self.select_mapper._instance( selectcontext, decorated_row, None)) # bypass and set directly: #instance.__dict__[self.key] = self.select_mapper._instance(selectcontext, decorated_row, None) else: # call _instance on the row, even though the object has been created, # so that we further descend into properties self.select_mapper._instance(selectcontext, decorated_row, None) else: if isnew: if self._should_log_debug: self.logger.debug( "initialize UniqueAppender on %s" % mapperutil.attribute_str(instance, self.key)) collection = sessionlib.attribute_manager.init_collection( instance, self.key) appender = util.UniqueAppender(collection, 'append_without_event') # store it in the "scratch" area, which is local to this load operation. selectcontext.attributes[(instance, self.key)] = appender result_list = selectcontext.attributes[(instance, self.key)] if self._should_log_debug: self.logger.debug( "eagerload list instance on %s" % mapperutil.attribute_str(instance, self.key)) self.select_mapper._instance(selectcontext, decorated_row, result_list) selectcontext.stack.pop()
def existing_execute(state, dict_, row): if (state, key) in context.attributes: result_list = context.attributes[(state, key)] else: # appender_key can be absent from context.attributes # with isnew=False when self-referential eager loading # is used; the same instance may be present in two # distinct sets of result columns collection = attributes.init_state_collection( state, dict_, key) result_list = util.UniqueAppender( collection, 'append_without_event') context.attributes[(state, key)] = result_list _instance(row, result_list)
def execute(state, row, isnew, **flags): if isnew or (state, key) not in context.attributes: # appender_key can be absent from context.attributes with isnew=False # when self-referential eager loading is used; the same instance may be present # in two distinct sets of result columns collection = attributes.init_collection(state, key) appender = util.UniqueAppender(collection, 'append_without_event') context.attributes[(state, key)] = appender result_list = context.attributes[(state, key)] _instance(row, result_list)
def execute(self, session, instance, row, identitykey, imap, isnew): """receive a row. tell our mapper to look for a new object instance in the row, and attach it to a list on the parent instance.""" decorated_row = self._decorate_row(row) try: # check for identity key identity_key = self.mapper._row_identity_key(decorated_row) except KeyError: # else degrade to a lazy loader LazyLoader.execute(self, session, instance, row, identitykey, imap, isnew) return if not self.uselist: if isnew: # set a scalar object instance directly on the parent object, # bypassing SmartProperty event handlers. instance.__dict__[self.key] = self.mapper._instance( session, decorated_row, imap, None) else: # call _instance on the row, even though the object has been created, # so that we further descend into properties self.mapper._instance(session, decorated_row, imap, None) return else: if isnew: # call the SmartProperty's initialize() method to create a new, blank list l = getattr(instance.__class__, self.key).initialize(instance) # create an appender object which will add set-like semantics to the list appender = util.UniqueAppender(l.data) # store it in the "scratch" area, which is local to this load operation. imap['_scratch'][(instance, self.key)] = appender result_list = imap['_scratch'][(instance, self.key)] self.mapper._instance(session, decorated_row, imap, result_list)
def process_row(self, selectcontext, instance, row, identitykey, isnew): """Receive a row. Tell our mapper to look for a new object instance in the row, and attach it to a list on the parent instance. """ if self in selectcontext.recursion_stack: return try: # check for row processor row_processor = selectcontext.attributes[id(self)] except KeyError: # create a row processor function and cache it in the context row_processor = self._create_row_processor(selectcontext, row) selectcontext.attributes[id(self)] = row_processor if row_processor is not None: decorated_row = row_processor(row) else: # row_processor was None: degrade to a lazy loader if self._should_log_debug: self.logger.debug("degrade to lazy loader on %s" % mapperutil.attribute_str(instance, self.key)) self.parent_property._get_strategy(LazyLoader).process_row( selectcontext, instance, row, identitykey, isnew) return # TODO: recursion check a speed hit...? try to get a "termination point" into the AliasedClauses # or EagerRowAdapter ? selectcontext.recursion_stack.add(self) try: if not self.uselist: if self._should_log_debug: self.logger.debug( "eagerload scalar instance on %s" % mapperutil.attribute_str(instance, self.key)) if isnew: # set a scalar object instance directly on the parent object, # bypassing SmartProperty event handlers. instance.__dict__[self.key] = self.mapper._instance( selectcontext, decorated_row, None) else: # call _instance on the row, even though the object has been created, # so that we further descend into properties self.mapper._instance(selectcontext, decorated_row, None) else: if isnew: if self._should_log_debug: self.logger.debug( "initialize UniqueAppender on %s" % mapperutil.attribute_str(instance, self.key)) # call the SmartProperty's initialize() method to create a new, blank list l = getattr(instance.__class__, self.key).initialize(instance) # create an appender object which will add set-like semantics to the list appender = util.UniqueAppender(l.data) # store it in the "scratch" area, which is local to this load operation. selectcontext.attributes[(instance, self.key)] = appender result_list = selectcontext.attributes[(instance, self.key)] if self._should_log_debug: self.logger.debug( "eagerload list instance on %s" % mapperutil.attribute_str(instance, self.key)) self.mapper._instance(selectcontext, decorated_row, result_list) finally: selectcontext.recursion_stack.remove(self)
def instances(self, cursor, *mappers_or_columns, **kwargs): """Return a list of mapped instances corresponding to the rows in a given *cursor* (i.e. ``ResultProxy``). \*mappers_or_columns is an optional list containing one or more of classes, mappers, strings or sql.ColumnElements which will be applied to each row and added horizontally to the result set, which becomes a list of tuples. The first element in each tuple is the usual result based on the mapper represented by this ``Query``. Each additional element in the tuple corresponds to an entry in the \*mappers_or_columns list. For each element in \*mappers_or_columns, if the element is a mapper or mapped class, an additional class instance will be present in the tuple. If the element is a string or sql.ColumnElement, the corresponding result column from each row will be present in the tuple. Note that when \*mappers_or_columns is present, "uniquing" for the result set is *disabled*, so that the resulting tuples contain entities as they actually correspond. this indicates that multiple results may be present if this option is used. """ self.__log_debug("instances()") session = self.session context = SelectionContext(self.select_mapper, session, self.extension, with_options=self.with_options, **kwargs) process = [] mappers_or_columns = tuple(self._entities) + mappers_or_columns if mappers_or_columns: for m in mappers_or_columns: if isinstance(m, type): m = mapper.class_mapper(m) if isinstance(m, mapper.Mapper): appender = [] def proc(context, row): if not m._instance(context, row, appender): appender.append(None) process.append((proc, appender)) elif isinstance(m, sql.ColumnElement) or isinstance(m, basestring): res = [] def proc(context, row): res.append(row[m]) process.append((proc, res)) result = [] else: result = util.UniqueAppender([]) for row in cursor.fetchall(): self.select_mapper._instance(context, row, result) for proc in process: proc[0](context, row) # store new stuff in the identity map for value in context.identity_map.values(): session._register_persistent(value) if mappers_or_columns: return zip(*([result] + [o[1] for o in process])) else: return result.data