def process_row(self, selectcontext, instance, row, identitykey, isnew): if isnew: if self._should_log_debug: self.logger.debug( "populating %s with %s/%s" % (mapperutil.attribute_str(instance, self.key), row.__class__.__name__, self.columns[0].key)) instance.__dict__[self.key] = row[self.columns[0]]
def process_row(self, selectcontext, instance, row, identitykey, isnew): if isnew: if not self.is_default or len(selectcontext.options): if self._should_log_debug: self.logger.debug( "set instance-level no loader on %s" % mapperutil.attribute_str(instance, self.key)) self._init_instance_attribute(instance)
def process_row(self, selectcontext, instance, row, identitykey, isnew): if isnew: # new object instance being loaded from a result row if not self.is_default or len(selectcontext.options): self.logger.debug("set instance-level lazy loader on %s" % mapperutil.attribute_str(instance, self.key)) # we are not the primary manager for this attribute on this class - set up a per-instance lazyloader, # which will override the clareset_instance_attributess-level behavior self._init_instance_attribute(instance, callable_=self.setup_loader( instance, selectcontext.options)) else: self.logger.debug("set class-level lazy loader on %s" % mapperutil.attribute_str(instance, self.key)) # we are the primary manager for this attribute on this class - reset its per-instance attribute state, # so that the class-level lazy loader is executed when next referenced on this instance. # this usually is not needed unless the constructor of the object referenced the attribute before we got # to load data into it. sessionlib.attribute_manager.reset_instance_attribute( instance, self.key)
def lazyload(): if self._should_log_debug: self.logger.debug("deferred load %s group %s" % (mapperutil.attribute_str( instance, self.key), str(self.group))) try: pk = self.parent.pks_by_table[self.columns[0].table] except KeyError: pk = self.columns[0].table.primary_key clause = sql.and_() for primary_key in pk: attr = self.parent.get_attr_by_column(instance, primary_key) if not attr: return None clause.clauses.append(primary_key == attr) session = sessionlib.object_session(instance) if session is None: raise exceptions.InvalidRequestError( "Parent instance %s is not bound to a Session; deferred load operation of attribute '%s' cannot proceed" % (instance.__class__, self.key)) localparent = mapper.object_mapper(instance) if self.group is not None: groupcols = [ p for p in localparent.props.values() if isinstance(p.strategy, DeferredColumnLoader) and p.group == self.group ] result = session.execute( localparent, sql.select([g.columns[0] for g in groupcols], clause, use_labels=True), None) try: row = result.fetchone() for prop in groupcols: if prop is self: continue # set a scalar object instance directly on the object, # bypassing SmartProperty event handlers. sessionlib.attribute_manager.init_instance_attribute( instance, prop.key, uselist=False) instance.__dict__[prop.key] = row[prop.columns[0]] return row[self.columns[0]] finally: result.close() else: return session.scalar( localparent, sql.select([self.columns[0]], clause, use_labels=True), None)
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)