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

📄 attributes.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
📖 第 1 页 / 共 3 页
字号:
    Only handles collections of instrumented objects.    InstrumentedCollectionAttribute holds an arbitrary, user-specified    container object (defaulting to a list) and brokers access to the    CollectionAdapter, a "view" onto that object that presents consistent    bag semantics to the orm layer independent of the user data implementation.    """    accepts_scalar_loader = False    def __init__(self, class_, key, callable_, typecallable=None, trackparent=False, extension=None, copy_function=None, compare_function=None, **kwargs):        super(CollectionAttributeImpl, self).__init__(class_,          key, callable_, trackparent=trackparent, extension=extension,          compare_function=compare_function, **kwargs)        if copy_function is None:            copy_function = self.__copy        self.copy = copy_function        if typecallable is None:            typecallable = list        self.collection_factory = \          collections._prepare_instrumentation(typecallable)        # may be removed in 0.5:        self.collection_interface = \          util.duck_type_collection(self.collection_factory())    def __copy(self, item):        return [y for y in list(collections.collection_adapter(item))]    def get_history(self, state, passive=False):        if self.key in state.dict:            return _create_history(self, state, state.dict[self.key])        else:            current = self.get(state, passive=passive)            if current is PASSIVE_NORESULT:                return (None, None, None)            else:                return _create_history(self, state, current)    def fire_append_event(self, state, value, initiator):        if self.key not in state.committed_state and self.key in state.dict:            state.committed_state[self.key] = self.copy(state.dict[self.key])        state.modified = True        if self.trackparent and value is not None:            self.sethasparent(value._state, True)        instance = state.obj()        for ext in self.extensions:            ext.append(instance, value, initiator or self)    def fire_pre_remove_event(self, state, initiator):        if self.key not in state.committed_state and self.key in state.dict:            state.committed_state[self.key] = self.copy(state.dict[self.key])    def fire_remove_event(self, state, value, initiator):        if self.key not in state.committed_state and self.key in state.dict:            state.committed_state[self.key] = self.copy(state.dict[self.key])        state.modified = True        if self.trackparent and value is not None:            self.sethasparent(value._state, False)        instance = state.obj()        for ext in self.extensions:            ext.remove(instance, value, initiator or self)    def get_history(self, state, passive=False):        current = self.get(state, passive=passive)        if current is PASSIVE_NORESULT:            return (None, None, None)        else:            return _create_history(self, state, current)    def delete(self, state):        if self.key not in state.dict:            return        state.modified = True        collection = self.get_collection(state)        collection.clear_with_event()        # TODO: catch key errors, convert to attributeerror?        del state.dict[self.key]    def initialize(self, state):        """Initialize this attribute on the given object instance with an empty collection."""        _, user_data = self._build_collection(state)        state.dict[self.key] = user_data        return user_data    def append(self, state, value, initiator, passive=False):        if initiator is self:            return        collection = self.get_collection(state, passive=passive)        if collection is PASSIVE_NORESULT:            state.get_pending(self.key).append(value)            self.fire_append_event(state, value, initiator)        else:            collection.append_with_event(value, initiator)    def remove(self, state, value, initiator, passive=False):        if initiator is self:            return        collection = self.get_collection(state, passive=passive)        if collection is PASSIVE_NORESULT:            state.get_pending(self.key).remove(value)            self.fire_remove_event(state, value, initiator)        else:            collection.remove_with_event(value, initiator)    def set(self, state, value, initiator):        """Set a value on the given object.        `initiator` is the ``InstrumentedAttribute`` that initiated the        ``set()` operation and is used to control the depth of a circular        setter operation.        """        if initiator is self:            return        # we need a CollectionAdapter to adapt the incoming value to an        # assignable iterable.  pulling a new collection first so that        # an adaptation exception does not trigger a lazy load of the        # old collection.        new_collection, user_data = self._build_collection(state)        new_values = list(new_collection.adapt_like_to_iterable(value))        old = self.get(state)        # ignore re-assignment of the current collection, as happens        # implicitly with in-place operators (foo.collection |= other)        if old is value:            return        if self.key not in state.committed_state:            state.committed_state[self.key] = self.copy(old)        old_collection = self.get_collection(state, old)        idset = util.IdentitySet        constants = idset(old_collection or []).intersection(new_values or [])        additions = idset(new_values or []).difference(constants)        removals  = idset(old_collection or []).difference(constants)        for member in new_values or ():            if member in additions:                new_collection.append_with_event(member)            elif member in constants:                new_collection.append_without_event(member)        state.dict[self.key] = user_data        state.modified = True        # mark all the orphaned elements as detached from the parent        if old_collection:            for member in removals:                old_collection.remove_with_event(member)            old_collection.unlink(old)    def set_committed_value(self, state, value):        """Set an attribute value on the given instance and 'commit' it.        Loads the existing collection from lazy callables in all cases.        """        collection, user_data = self._build_collection(state)        if value:            for item in value:                collection.append_without_event(item)        state.callables.pop(self.key, None)        state.dict[self.key] = user_data        if self.key in state.pending:            # pending items.  commit loaded data, add/remove new data            state.committed_state[self.key] = list(value or [])            added = state.pending[self.key].added_items            removed = state.pending[self.key].deleted_items            for item in added:                collection.append_without_event(item)            for item in removed:                collection.remove_without_event(item)            del state.pending[self.key]        elif self.key in state.committed_state:            # no pending items.  remove committed state if any.            # (this can occur with an expired attribute)            del state.committed_state[self.key]        return user_data    def _build_collection(self, state):        """build a new, blank collection and return it wrapped in a CollectionAdapter."""        user_data = self.collection_factory()        collection = collections.CollectionAdapter(self, state, user_data)        return collection, user_data    def get_collection(self, state, user_data=None, passive=False):        """retrieve the CollectionAdapter associated with the given state.        Creates a new CollectionAdapter if one does not exist.        """        if user_data is None:            user_data = self.get(state, passive=passive)            if user_data is PASSIVE_NORESULT:                return user_data        try:            return getattr(user_data, '_sa_adapter')        except AttributeError:            # TODO: this codepath never occurs, and this             # except/initialize should be removed            collections.CollectionAdapter(self, state, user_data)            return getattr(user_data, '_sa_adapter')class GenericBackrefExtension(interfaces.AttributeExtension):    """An extension which synchronizes a two-way relationship.    A typical two-way relationship is a parent object containing a    list of child objects, where each child object references the    parent.  The other are two objects which contain scalar references    to each other.    """    def __init__(self, key):        self.key = key    def set(self, instance, child, oldchild, initiator):        if oldchild is child:            return        if oldchild is not None:            # With lazy=None, there's no guarantee that the full collection is            # present when updating via a backref.            impl = getattr(oldchild.__class__, self.key).impl            try:                impl.remove(oldchild._state, instance, initiator, passive=True)            except (ValueError, KeyError, IndexError):                pass        if child is not None:            getattr(child.__class__, self.key).impl.append(child._state, instance, initiator, passive=True)    def append(self, instance, child, initiator):        getattr(child.__class__, self.key).impl.append(child._state, instance, initiator, passive=True)    def remove(self, instance, child, initiator):        if child is not None:            getattr(child.__class__, self.key).impl.remove(child._state, instance, initiator, passive=True)class ClassState(object):    """tracks state information at the class level."""    def __init__(self):        self.mappers = {}        self.attrs = {}        self.has_mutable_scalars = Falseclass InstanceState(object):    """tracks state information at the instance level."""    def __init__(self, obj):        self.class_ = obj.__class__        self.obj = weakref.ref(obj, self.__cleanup)        self.dict = obj.__dict__        self.committed_state = {}        self.modified = False        self.callables = {}        self.parents = {}        self.pending = {}        self.appenders = {}        self.instance_dict = None        self.runid = None    def __cleanup(self, ref):        # tiptoe around Python GC unpredictableness        instance_dict = self.instance_dict        if instance_dict is None:            return        instance_dict = instance_dict()        if instance_dict is None or instance_dict._mutex is None:            return        # the mutexing here is based on the assumption that gc.collect()        # may be firing off cleanup handlers in a different thread than that        # which is normally operating upon the instance dict.        instance_dict._mutex.acquire()        try:            try:                self.__resurrect(instance_dict)            except:                # catch app cleanup exceptions.  no other way around this                # without warnings being produced                pass        finally:            instance_dict._mutex.release()    def _check_resurrect(self, instance_dict):        instance_dict._mutex.acquire()        try:            return self.obj() or self.__resurrect(instance_dict)        finally:            instance_dict._mutex.release()    def get_pending(self, key):        if key not in self.pending:            self.pending[key] = PendingCollection()        return self.pending[key]    def is_modified(self):        if self.modified:            return True        elif self.class_._class_state.has_mutable_scalars:            for attr in _managed_attributes(self.class_):                if hasattr(attr.impl, 'check_mutable_modified') and attr.impl.check_mutable_modified(self):                    return True            else:                return False        else:            return False    def __resurrect(self, instance_dict):        if self.is_modified():            # store strong ref'ed version of the object; will revert            # to weakref when changes are persisted            obj = new_instance(self.class_, state=self)            self.obj = weakref.ref(obj, self.__cleanup)            self._strong_obj = obj            obj.__dict__.update(self.dict)            self.dict = obj.__dict__            return obj        else:            del instance_dict[self.dict['_instance_key']]            return None    def __getstate__(self):        return {'committed_state':self.committed_state, 'pending':self.pending, 'parents':self.parents, 'modified':self.modified, 'instance':self.obj(), 'expired_attributes':getattr(self, 'expired_attributes', None), 'callables':self.callables}    def __setstate__(self, state):        self.committed_state = state['committed_state']        self.parents = state['parents']        self.pending = state['pending']        self.modified = state['modified']        self.obj = weakref.ref(state['instance'])        self.class_ = self.obj().__class__        self.dict = self.obj().__dict__        self.callables = state['callables']        self.runid = None        self.appenders = {}        if state['expired_attributes'] is not None:            self.expire_attributes(state['expired_attributes'])    def initialize(self, key):        getattr(self.class_, key).impl.initialize(self)    def set_callable(self, key, callable_):        self.dict.pop(key, None)        self.callables[key] = callable_    def __call__(self):        """__call__ allows the InstanceState to act as a deferred        callable for loading expired attributes, which is also        serializable.        """        instance = self.obj()                unmodified = self.unmodified        self.class_._class_state.deferred_scalar_loader(instance, [            attr.impl.key for attr in _managed_attributes(self.class_) if                 attr.impl.accepts_scalar_loader and                 attr.impl.key in self.expired_attributes and                 attr.impl.key in unmodified            ])        for k in self.expired_attributes:            self.callables.pop(k, None)        self.expired_attributes.clear()        return ATTR_WAS_SET    def unmodified(self):        """a set of keys which have no uncommitted changes"""        return util.Set([            attr.impl.key for attr in _managed_attributes(self.class_) if            attr.impl.key not in self.committed_state            and (not hasattr(attr.impl, 'commit_to_state') or not attr.impl.check_mutable_modified(self))        ])    unmodified = property(unmodified)    def expire_attributes(self, attribute_names):        if not hasattr(self, 'expired_attributes'):            self.expired_attributes = util.Set()        if attribute_names is None:            for attr in _managed_attributes(self.class_):                self.dict.pop(attr.impl.key, None)                self.expired_attributes.add(attr.impl.key)                if attr.impl.accepts_scalar_loader:                    self.callables[attr.impl.key] = self            self.committed_state = {}        else:            for key in attribute_names:

⌨️ 快捷键说明

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