⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strategies.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
📖 第 1 页 / 共 3 页
字号:
        self._register_attribute(self.parent.class_, dynamic=True, target_mapper=self.parent_property.mapper)    def create_row_processor(self, selectcontext, mapper, row):        return (None, None, None)DynaLoader.logger = logging.class_logger(DynaLoader)        class NoLoader(AbstractRelationLoader):    def init_class_attribute(self):        self.is_class_level = True        self._register_attribute(self.parent.class_)    def create_row_processor(self, selectcontext, mapper, row):        def new_execute(instance, row, ispostselect, **flags):            if not ispostselect:                if self._should_log_debug:                    self.logger.debug("initializing blank scalar/collection on %s" % mapperutil.attribute_str(instance, self.key))                self._init_instance_attribute(instance)        return (new_execute, None, None)NoLoader.logger = logging.class_logger(NoLoader)        class LazyLoader(AbstractRelationLoader):    def init(self):        super(LazyLoader, self).init()        (self.lazywhere, self.lazybinds, self.equated_columns) = self._create_lazy_clause(self.parent_property)                self.logger.info(str(self.parent_property) + " lazy loading clause " + str(self.lazywhere))        # determine if our "lazywhere" clause is the same as the mapper's        # get() clause.  then we can just use mapper.get()        #from sqlalchemy.orm import query        self.use_get = not self.uselist and self.mapper._get_clause[0].compare(self.lazywhere)        if self.use_get:            self.logger.info(str(self.parent_property) + " will use query.get() to optimize instance loads")    def init_class_attribute(self):        self.is_class_level = True        self._register_attribute(self.parent.class_, callable_=self.class_level_loader)    def lazy_clause(self, instance, reverse_direction=False):        if instance is None:            return self._lazy_none_clause(reverse_direction)                    if not reverse_direction:            (criterion, lazybinds, rev) = (self.lazywhere, self.lazybinds, self.equated_columns)        else:            (criterion, lazybinds, rev) = LazyLoader._create_lazy_clause(self.parent_property, reverse_direction=reverse_direction)        bind_to_col = dict([(lazybinds[col].key, col) for col in lazybinds])        def visit_bindparam(bindparam):            mapper = reverse_direction and self.parent_property.mapper or self.parent_property.parent            if bindparam.key in bind_to_col:                # use the "committed" (database) version to get query column values                bindparam.value = mapper._get_committed_attr_by_column(instance, bind_to_col[bindparam.key])        return visitors.traverse(criterion, clone=True, visit_bindparam=visit_bindparam)        def _lazy_none_clause(self, reverse_direction=False):        if not reverse_direction:            (criterion, lazybinds, rev) = (self.lazywhere, self.lazybinds, self.equated_columns)        else:            (criterion, lazybinds, rev) = LazyLoader._create_lazy_clause(self.parent_property, reverse_direction=reverse_direction)        bind_to_col = dict([(lazybinds[col].key, col) for col in lazybinds])        def visit_binary(binary):            mapper = reverse_direction and self.parent_property.mapper or self.parent_property.parent            if isinstance(binary.left, expression._BindParamClause) and binary.left.key in bind_to_col:                # reverse order if the NULL is on the left side                binary.left = binary.right                binary.right = expression.null()                binary.operator = operators.is_            elif isinstance(binary.right, expression._BindParamClause) and binary.right.key in bind_to_col:                binary.right = expression.null()                binary.operator = operators.is_                return visitors.traverse(criterion, clone=True, visit_binary=visit_binary)            def class_level_loader(self, instance, options=None, path=None):        if not mapper.has_mapper(instance):            return None        localparent = mapper.object_mapper(instance)        # adjust for the PropertyLoader associated with the instance        # not being our own PropertyLoader.  This can occur when entity_name        # mappers are used to map different versions of the same PropertyLoader        # to the class.        prop = localparent.get_property(self.key)        if prop is not self.parent_property:            return prop._get_strategy(LazyLoader).setup_loader(instance)                return LoadLazyAttribute(instance, self.key, options, path)    def setup_loader(self, instance, options=None, path=None):        return LoadLazyAttribute(instance, self.key, options, path)    def create_row_processor(self, selectcontext, mapper, row):        if not self.is_class_level or len(selectcontext.options):            def new_execute(instance, row, ispostselect, **flags):                if not ispostselect:                    if self._should_log_debug:                        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 class-level behavior                                        self._init_instance_attribute(instance, callable_=self.setup_loader(instance, selectcontext.options, selectcontext.query._current_path + selectcontext.path))            return (new_execute, None, None)        else:            def new_execute(instance, row, ispostselect, **flags):                if not ispostselect:                    if self._should_log_debug:                        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.                    instance._state.reset(self.key)            return (new_execute, None, None)    def _create_lazy_clause(cls, prop, reverse_direction=False):        (primaryjoin, secondaryjoin, remote_side) = (prop.polymorphic_primaryjoin, prop.polymorphic_secondaryjoin, prop.remote_side)                binds = {}        equated_columns = {}        def should_bind(targetcol, othercol):            if not prop._col_is_part_of_mappings(targetcol):                return False                            if reverse_direction and not secondaryjoin:                return targetcol in remote_side            else:                return othercol in remote_side        def visit_binary(binary):            if not isinstance(binary.left, sql.ColumnElement) or not isinstance(binary.right, sql.ColumnElement):                return            leftcol = binary.left            rightcol = binary.right            equated_columns[rightcol] = leftcol            equated_columns[leftcol] = rightcol            if should_bind(leftcol, rightcol):                if leftcol in binds:                    binary.left = binds[leftcol]                else:                    binary.left = binds[leftcol] = sql.bindparam(None, None, type_=binary.right.type)            # the "left is not right" compare is to handle part of a join clause that is "table.c.col1==table.c.col1",            # which can happen in rare cases (test/orm/relationships.py RelationTest2)            if leftcol is not rightcol and should_bind(rightcol, leftcol):                if rightcol in binds:                    binary.right = binds[rightcol]                else:                    binary.right = binds[rightcol] = sql.bindparam(None, None, type_=binary.left.type)                        lazywhere = primaryjoin                if not secondaryjoin or not reverse_direction:            lazywhere = visitors.traverse(lazywhere, clone=True, visit_binary=visit_binary)                if secondaryjoin is not None:            if reverse_direction:                secondaryjoin = visitors.traverse(secondaryjoin, clone=True, visit_binary=visit_binary)            lazywhere = sql.and_(lazywhere, secondaryjoin)        return (lazywhere, binds, equated_columns)    _create_lazy_clause = classmethod(_create_lazy_clause)    LazyLoader.logger = logging.class_logger(LazyLoader)class LoadLazyAttribute(object):    """callable, serializable loader object used by LazyLoader"""    def __init__(self, instance, key, options, path):        self.instance = instance        self.key = key        self.options = options        self.path = path            def __getstate__(self):        return {'instance':self.instance, 'key':self.key, 'options':self.options, 'path':serialize_path(self.path)}    def __setstate__(self, state):        self.instance = state['instance']        self.key = state['key']        self.options= state['options']        self.path = deserialize_path(state['path'])            def __call__(self):        instance = self.instance                if not mapper.has_identity(instance):            return None        instance_mapper = mapper.object_mapper(instance)        prop = instance_mapper.get_property(self.key)        strategy = prop._get_strategy(LazyLoader)                if strategy._should_log_debug:            strategy.logger.debug("lazy load attribute %s on instance %s" % (self.key, mapperutil.instance_str(instance)))        session = sessionlib.object_session(instance)        if session is None:            try:                session = instance_mapper.get_session()            except exceptions.InvalidRequestError:                raise exceptions.UnboundExecutionError("Parent instance %s is not bound to a Session, and no contextual session is established; lazy load operation of attribute '%s' cannot proceed" % (instance.__class__, self.key))        q = session.query(prop.mapper).autoflush(False)        if self.path:            q = q._with_current_path(self.path)                    # if we have a simple primary key load, use mapper.get()        # to possibly save a DB round trip        if strategy.use_get:            ident = []            allnulls = True            for primary_key in prop.select_mapper.primary_key:                 val = instance_mapper._get_committed_attr_by_column(instance, strategy.equated_columns[primary_key])                allnulls = allnulls and val is None                ident.append(val)            if allnulls:                return None            if self.options:                q = q._conditional_options(*self.options)            return q.get(ident)                    if strategy.order_by is not False:            q = q.order_by(strategy.order_by)        elif strategy.secondary is not None and strategy.secondary.default_order_by() is not None:            q = q.order_by(strategy.secondary.default_order_by())        if self.options:            q = q._conditional_options(*self.options)        q = q.filter(strategy.lazy_clause(instance))        result = q.all()        if strategy.uselist:            return result        else:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -