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

📄 session.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
📖 第 1 页 / 共 4 页
字号:
    def _cascade_save_or_update(self, instance):        for obj, mapper in _cascade_iterator('save-update', instance, halt_on=lambda c:c in self):            self._save_or_update_impl(obj, mapper.entity_name)    def delete(self, instance):        """Mark the given instance as deleted.        The delete operation occurs upon ``flush()``.        """        self._delete_impl(instance)        for c, m in _cascade_iterator('delete', instance):            self._delete_impl(c, ignore_transient=True)    def merge(self, instance, entity_name=None, dont_load=False, _recursive=None):        """Copy the state of the given `instance` onto the persistent        instance with the same identifier.        If there is no persistent instance currently associated with        the session, it will be loaded.  Return the persistent        instance. If the given instance is unsaved, save a copy of and        return it as a newly persistent instance. The given instance        does not become associated with the session.        This operation cascades to associated instances if the        association is mapped with ``cascade="merge"``.        """        if _recursive is None:            _recursive = {}  # TODO: this should be an IdentityDict for instances, but will need a separate                             # dict for PropertyLoader tuples        if entity_name is not None:            mapper = _class_mapper(instance.__class__, entity_name=entity_name)        else:            mapper = _object_mapper(instance)        if instance in _recursive:            return _recursive[instance]        key = getattr(instance, '_instance_key', None)        if key is None:            if dont_load:                raise exceptions.InvalidRequestError("merge() with dont_load=True option does not support objects transient (i.e. unpersisted) objects.  flush() all changes on mapped instances before merging with dont_load=True.")            merged = attributes.new_instance(mapper.class_)        else:            if key in self.identity_map:                merged = self.identity_map[key]            elif dont_load:                if instance._state.modified:                    raise exceptions.InvalidRequestError("merge() with dont_load=True option does not support objects marked as 'dirty'.  flush() all changes on mapped instances before merging with dont_load=True.")                merged = attributes.new_instance(mapper.class_)                merged._instance_key = key                merged._entity_name = entity_name                self._update_impl(merged, entity_name=mapper.entity_name)            else:                merged = self.get(mapper.class_, key[1])                if merged is None:                    raise exceptions.AssertionError("Instance %s has an instance key but is not persisted" % mapperutil.instance_str(instance))        _recursive[instance] = merged        for prop in mapper.iterate_properties:            prop.merge(self, instance, merged, dont_load, _recursive)        if key is None:            self.save(merged, entity_name=mapper.entity_name)        elif dont_load:            merged._state.commit_all()        return merged    def identity_key(cls, *args, **kwargs):        """Get an identity key.        Valid call signatures:        * ``identity_key(class, ident, entity_name=None)``          class              mapped class (must be a positional argument)          ident              primary key, if the key is composite this is a tuple          entity_name              optional entity name        * ``identity_key(instance=instance)``          instance              object instance (must be given as a keyword arg)        * ``identity_key(class, row=row, entity_name=None)``          class              mapped class (must be a positional argument)          row              result proxy row (must be given as a keyword arg)          entity_name              optional entity name (must be given as a keyword arg)        """        if args:            if len(args) == 1:                class_ = args[0]                try:                    row = kwargs.pop("row")                except KeyError:                    ident = kwargs.pop("ident")                entity_name = kwargs.pop("entity_name", None)            elif len(args) == 2:                class_, ident = args                entity_name = kwargs.pop("entity_name", None)            elif len(args) == 3:                class_, ident, entity_name = args            else:                raise exceptions.ArgumentError("expected up to three "                    "positional arguments, got %s" % len(args))            if kwargs:                raise exceptions.ArgumentError("unknown keyword arguments: %s"                    % ", ".join(kwargs.keys()))            mapper = _class_mapper(class_, entity_name=entity_name)            if "ident" in locals():                return mapper.identity_key_from_primary_key(ident)            return mapper.identity_key_from_row(row)        instance = kwargs.pop("instance")        if kwargs:            raise exceptions.ArgumentError("unknown keyword arguments: %s"                % ", ".join(kwargs.keys()))        mapper = _object_mapper(instance)        return mapper.identity_key_from_instance(instance)    identity_key = classmethod(identity_key)    def object_session(cls, instance):        """Return the ``Session`` to which the given object belongs."""        return object_session(instance)    object_session = classmethod(object_session)    def _save_impl(self, instance, **kwargs):        if hasattr(instance, '_instance_key'):            raise exceptions.InvalidRequestError("Instance '%s' is already persistent" % mapperutil.instance_str(instance))        else:            # TODO: consolidate the steps here            attributes.manage(instance)            instance._entity_name = kwargs.get('entity_name', None)            self._attach(instance)            self.uow.register_new(instance)    def _update_impl(self, instance, **kwargs):        if instance in self and instance not in self.deleted:            return        if not hasattr(instance, '_instance_key'):            raise exceptions.InvalidRequestError("Instance '%s' is not persisted" % mapperutil.instance_str(instance))        elif self.identity_map.get(instance._instance_key, instance) is not instance:            raise exceptions.InvalidRequestError("Could not update instance '%s', identity key %s; a different instance with the same identity key already exists in this session." % (mapperutil.instance_str(instance), instance._instance_key))        self._attach(instance)    def _save_or_update_impl(self, instance, entity_name=None):        key = getattr(instance, '_instance_key', None)        if key is None:            self._save_impl(instance, entity_name=entity_name)        else:            self._update_impl(instance, entity_name=entity_name)    def _delete_impl(self, instance, ignore_transient=False):        if instance in self and instance in self.deleted:            return        if not hasattr(instance, '_instance_key'):            if ignore_transient:                return            else:                raise exceptions.InvalidRequestError("Instance '%s' is not persisted" % mapperutil.instance_str(instance))        if self.identity_map.get(instance._instance_key, instance) is not instance:            raise exceptions.InvalidRequestError("Instance '%s' is with key %s already persisted with a different identity" % (mapperutil.instance_str(instance), instance._instance_key))        self._attach(instance)        self.uow.register_deleted(instance)    def _attach(self, instance):        old_id = getattr(instance, '_sa_session_id', None)        if old_id != self.hash_key:            if old_id is not None and old_id in _sessions and instance in _sessions[old_id]:                raise exceptions.InvalidRequestError("Object '%s' is already attached "                                                     "to session '%s' (this is '%s')" %                                                     (mapperutil.instance_str(instance), old_id, id(self)))            key = getattr(instance, '_instance_key', None)            if key is not None:                self.identity_map[key] = instance            instance._sa_session_id = self.hash_key    def _unattach(self, instance):        if instance._sa_session_id == self.hash_key:            del instance._sa_session_id    def _validate_persistent(self, instance):        """Validate that the given instance is persistent within this        ``Session``.        """        return instance in self    def __contains__(self, instance):        """Return True if the given instance is associated with this session.        The instance may be pending or persistent within the Session for a        result of True.        """        return instance._state in self.uow.new or (hasattr(instance, '_instance_key') and self.identity_map.get(instance._instance_key) is instance)    def __iter__(self):        """Return an iterator of all instances which are pending or persistent within this Session."""        return iter(list(self.uow.new.values()) + self.uow.identity_map.values())    def is_modified(self, instance, include_collections=True, passive=False):        """Return True if the given instance has modified attributes.        This method retrieves a history instance for each instrumented attribute        on the instance and performs a comparison of the current value to its        previously committed value.  Note that instances present in the 'dirty'        collection may result in a value of ``False`` when tested with this method.        `include_collections` indicates if multivalued collections should be included        in the operation.  Setting this to False is a way to detect only local-column        based properties (i.e. scalar columns or many-to-one foreign keys) that would        result in an UPDATE for this instance upon flush.        The `passive` flag indicates if unloaded attributes and collections should        not be loaded in the course of performing this test.        """        for attr in attributes._managed_attributes(instance.__class__):            if not include_collections and hasattr(attr.impl, 'get_collection'):                continue            (added, unchanged, deleted) = attr.get_history(instance)            if added or deleted:                return True        return False    def dirty(self):        """Return a ``Set`` of all instances marked as 'dirty' within this ``Session``.        Note that the 'dirty' state here is 'optimistic'; most attribute-setting or collection        modification operations will mark an instance as 'dirty' and place it in this set,        even if there is no net change to the attribute's value.  At flush time, the value        of each attribute is compared to its previously saved value,        and if there's no net change, no SQL operation will occur (this is a more expensive        operation so it's only done at flush time).        To check if an instance has actionable net changes to its attributes, use the        is_modified() method.        """        return self.uow.locate_dirty()    dirty = property(dirty)    def deleted(self):        "Return a ``Set`` of all instances marked as 'deleted' within this ``Session``"                return util.IdentitySet(self.uow.deleted.values())    deleted = property(deleted)    def new(self):        "Return a ``Set`` of all instances marked as 'new' within this ``Session``."                return util.IdentitySet(self.uow.new.values())    new = property(new)def _expire_state(state, attribute_names):    """Standalone expire instance function.    Installs a callable with the given instance's _state    which will fire off when any of the named attributes are accessed;    their existing value is removed.    If the list is None or blank, the entire instance is expired.    """    state.expire_attributes(attribute_names)register_attribute = unitofwork.register_attribute_sessions = weakref.WeakValueDictionary()def _cascade_iterator(cascade, instance, **kwargs):    mapper = _object_mapper(instance)    for (o, m) in mapper.cascade_iterator(cascade, instance._state, **kwargs):        yield o, mdef object_session(instance):    """Return the ``Session`` to which the given instance is bound, or ``None`` if none."""    hashkey = getattr(instance, '_sa_session_id', None)    if hashkey is not None:        sess = _sessions.get(hashkey)        if sess is not None and instance in sess:            return sess    return None# Lazy initialization to avoid circular importsunitofwork.object_session = object_sessionfrom sqlalchemy.orm import mappermapper._expire_state = _expire_state

⌨️ 快捷键说明

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