📄 session.py
字号:
"""Close this Session. This clears all items and ends any transaction in progress. If this session were created with ``transactional=True``, a new transaction is immediately begun. Note that this new transaction does not use any connection resources until they are first needed. """ self.clear() if self.transaction is not None: for transaction in self.transaction._iterate_parents(): transaction.close() if self.transactional: # note this doesnt use any connection resources self.begin() def close_all(cls): """Close *all* sessions in memory.""" for sess in _sessions.values(): sess.close() close_all = classmethod(close_all) def clear(self): """Remove all object instances from this ``Session``. This is equivalent to calling ``expunge()`` for all objects in this ``Session``. """ for instance in self: self._unattach(instance) self.uow = unitofwork.UnitOfWork(self) self.identity_map = self.uow.identity_map # TODO: need much more test coverage for bind_mapper() and similar ! def bind_mapper(self, mapper, bind, entity_name=None): """Bind the given `mapper` or `class` to the given ``Engine`` or ``Connection``. All subsequent operations involving this ``Mapper`` will use the given `bind`. """ if isinstance(mapper, type): mapper = _class_mapper(mapper, entity_name=entity_name) self.__binds[mapper.base_mapper] = bind for t in mapper._all_tables: self.__binds[t] = bind def bind_table(self, table, bind): """Bind the given `table` to the given ``Engine`` or ``Connection``. All subsequent operations involving this ``Table`` will use the given `bind`. """ self.__binds[table] = bind def get_bind(self, mapper, clause=None, **kwargs): """Return an engine corresponding to the given arguments. mapper mapper relative to the desired operation clause a ClauseElement which is to be executed. if mapper is not present, this may be used to locate Table objects, which are then associated with mappers which have associated binds. \**kwargs Subclasses (i.e. ShardedSession) may add additional arguments to get_bind() which are passed through here. """ if mapper is None and clause is None: if self.bind is not None: return self.bind else: raise exceptions.UnboundExecutionError("This session is unbound to any Engine or Connection; specify a mapper to get_bind()") elif len(self.__binds): if mapper is not None: if isinstance(mapper, type): mapper = _class_mapper(mapper) if mapper.base_mapper in self.__binds: return self.__binds[mapper.base_mapper] elif mapper.compile().mapped_table in self.__binds: return self.__binds[mapper.mapped_table] if clause is not None: for t in clause._table_iterator(): if t in self.__binds: return self.__binds[t] if self.bind is not None: return self.bind elif mapper is None: raise exceptions.UnboundExecutionError("Could not locate any mapper associated with SQL expression") else: if isinstance(mapper, type): mapper = _class_mapper(mapper) else: mapper = mapper.compile() e = mapper.mapped_table.bind if e is None: raise exceptions.UnboundExecutionError("Could not locate any Engine or Connection bound to mapper '%s'" % str(mapper)) return e def query(self, mapper_or_class, *addtl_entities, **kwargs): """Return a new ``Query`` object corresponding to this ``Session`` and the mapper, or the classes' primary mapper. """ entity_name = kwargs.pop('entity_name', None) if isinstance(mapper_or_class, type): q = self._query_cls(_class_mapper(mapper_or_class, entity_name=entity_name), self, **kwargs) else: q = self._query_cls(mapper_or_class, self, **kwargs) for ent in addtl_entities: q = q.add_entity(ent) return q def sql(self): class SQLProxy(object): def __getattr__(self, key): def call(*args, **kwargs): kwargs[engine] = self.engine return getattr(sql, key)(*args, **kwargs) sql = property(sql) def _autoflush(self): if self.autoflush and (self.transaction is None or self.transaction.autoflush): self.flush() def flush(self, objects=None): """Flush all the object modifications present in this session to the database. `objects` is a list or tuple of objects specifically to be flushed; if ``None``, all new and modified objects are flushed. """ self.uow.flush(self, objects) def get(self, class_, ident, **kwargs): """Return an instance of the object based on the given identifier, or ``None`` if not found. The `ident` argument is a scalar or tuple of primary key column values in the order of the table def's primary key columns. The `entity_name` keyword argument may also be specified which further qualifies the underlying Mapper used to perform the query. """ entity_name = kwargs.pop('entity_name', None) return self.query(class_, entity_name=entity_name).get(ident, **kwargs) def load(self, class_, ident, **kwargs): """Return an instance of the object based on the given identifier. If not found, raises an exception. The method will **remove all pending changes** to the object already existing in the ``Session``. The `ident` argument is a scalar or tuple of primary key columns in the order of the table def's primary key columns. The `entity_name` keyword argument may also be specified which further qualifies the underlying ``Mapper`` used to perform the query. """ entity_name = kwargs.pop('entity_name', None) return self.query(class_, entity_name=entity_name).load(ident, **kwargs) def refresh(self, instance, attribute_names=None): """Refresh the attributes on the given instance. When called, a query will be issued to the database which will refresh all attributes with their current value. Lazy-loaded relational attributes will remain lazily loaded, so that the instance-wide refresh operation will be followed immediately by the lazy load of that attribute. Eagerly-loaded relational attributes will eagerly load within the single refresh operation. The ``attribute_names`` argument is an iterable collection of attribute names indicating a subset of attributes to be refreshed. """ self._validate_persistent(instance) if self.query(_object_mapper(instance))._get(instance._instance_key, refresh_instance=instance._state, only_load_props=attribute_names) is None: raise exceptions.InvalidRequestError("Could not refresh instance '%s'" % mapperutil.instance_str(instance)) def expire_all(self): """Expires all persistent instances within this Session. """ for state in self.identity_map.all_states(): _expire_state(state, None) def expire(self, instance, attribute_names=None): """Expire the attributes on the given instance. The instance's attributes are instrumented such that when an attribute is next accessed, a query will be issued to the database which will refresh all attributes with their current value. The ``attribute_names`` argument is an iterable collection of attribute names indicating a subset of attributes to be expired. """ if attribute_names: self._validate_persistent(instance) _expire_state(instance._state, attribute_names=attribute_names) else: # pre-fetch the full cascade since the expire is going to # remove associations cascaded = list(_cascade_iterator('refresh-expire', instance)) self._validate_persistent(instance) _expire_state(instance._state, None) for (c, m) in cascaded: self._validate_persistent(c) _expire_state(c._state, None) def prune(self): """Remove unreferenced instances cached in the identity map. Note that this method is only meaningful if "weak_identity_map" is set to False. Removes any object in this Session's identity map that is not referenced in user code, modified, new or scheduled for deletion. Returns the number of objects pruned. """ return self.uow.prune_identity_map() def expunge(self, instance): """Remove the given `instance` from this ``Session``. This will free all internal references to the instance. Cascading will be applied according to the *expunge* cascade rule. """ self._validate_persistent(instance) for c, m in [(instance, None)] + list(_cascade_iterator('expunge', instance)): if c in self: self.uow._remove_deleted(c._state) self._unattach(c) def save(self, instance, entity_name=None): """Add a transient (unsaved) instance to this ``Session``. This operation cascades the `save_or_update` method to associated instances if the relation is mapped with ``cascade="save-update"``. The `entity_name` keyword argument will further qualify the specific ``Mapper`` used to handle this instance. """ self._save_impl(instance, entity_name=entity_name) self._cascade_save_or_update(instance) def update(self, instance, entity_name=None): """Bring the given detached (saved) instance into this ``Session``. If there is a persistent instance with the same instance key, but different identity already associated with this ``Session``, an InvalidRequestError exception is thrown. This operation cascades the `save_or_update` method to associated instances if the relation is mapped with ``cascade="save-update"``. """ self._update_impl(instance, entity_name=entity_name) self._cascade_save_or_update(instance) def save_or_update(self, instance, entity_name=None): """Save or update the given instance into this ``Session``. The presence of an `_instance_key` attribute on the instance determines whether to ``save()`` or ``update()`` the instance. """ self._save_or_update_impl(instance, entity_name=entity_name) self._cascade_save_or_update(instance)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -