예제 #1
0
            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)
예제 #2
0
 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)
예제 #3
0
 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)
예제 #4
0
            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()
예제 #5
0
 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)
예제 #6
0
                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)
예제 #7
0
파일: properties.py 프로젝트: calston/tums
    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)
예제 #8
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)
예제 #9
0
    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