Example #1
0
 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]]
Example #2
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)
Example #3
0
 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)
Example #4
0
        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)
Example #5
0
    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)