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

📄 session.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
📖 第 1 页 / 共 4 页
字号:
# session.py# Copyright (C) 2005, 2006, 2007, 2008 Michael Bayer mike_mp@zzzcomputing.com## This module is part of SQLAlchemy and is released under# the MIT License: http://www.opensource.org/licenses/mit-license.php"""Provides the Session class and related utilities."""import weakreffrom sqlalchemy import util, exceptions, sql, enginefrom sqlalchemy.orm import unitofwork, query, attributes, util as mapperutilfrom sqlalchemy.orm.mapper import object_mapper as _object_mapperfrom sqlalchemy.orm.mapper import class_mapper as _class_mapperfrom sqlalchemy.orm.mapper import Mapper__all__ = ['Session', 'SessionTransaction', 'SessionExtension']def sessionmaker(bind=None, class_=None, autoflush=True, transactional=True, **kwargs):    """Generate a custom-configured [sqlalchemy.orm.session#Session] class.    The returned object is a subclass of ``Session``, which, when instantiated with no    arguments, uses the keyword arguments configured here as its constructor arguments.    It is intended that the `sessionmaker()` function be called within the global scope    of an application, and the returned class be made available to the rest of the    application as the single class used to instantiate sessions.    e.g.::        # global scope        Session = sessionmaker(autoflush=False)        # later, in a local scope, create and use a session:        sess = Session()    Any keyword arguments sent to the constructor itself will override the "configured"    keywords::        Session = sessionmaker()        # bind an individual session to a connection        sess = Session(bind=connection)    The class also includes a special classmethod ``configure()``, which allows    additional configurational options to take place after the custom ``Session``    class has been generated.  This is useful particularly for defining the    specific ``Engine`` (or engines) to which new instances of ``Session``    should be bound::        Session = sessionmaker()        Session.configure(bind=create_engine('sqlite:///foo.db'))        sess = Session()    The function features a single keyword argument of its own, `class_`, which    may be used to specify an alternate class other than ``sqlalchemy.orm.session.Session``    which should be used by the returned class.  All other keyword arguments sent to    `sessionmaker()` are passed through to the instantiated `Session()` object.    """    kwargs['bind'] = bind    kwargs['autoflush'] = autoflush    kwargs['transactional'] = transactional    if class_ is None:        class_ = Session    class Sess(class_):        def __init__(self, **local_kwargs):            for k in kwargs:                local_kwargs.setdefault(k, kwargs[k])            super(Sess, self).__init__(**local_kwargs)        def configure(self, **new_kwargs):            """(re)configure the arguments for this sessionmaker.            e.g.                Session = sessionmaker()                Session.configure(bind=create_engine('sqlite://'))            """            kwargs.update(new_kwargs)        configure = classmethod(configure)    return Sessclass SessionExtension(object):    """An extension hook object for Sessions.  Subclasses may be installed into a Session    (or sessionmaker) using the ``extension`` keyword argument.    """    def before_commit(self, session):        """Execute right before commit is called.        Note that this may not be per-flush if a longer running transaction is ongoing."""    def after_commit(self, session):        """Execute after a commit has occured.        Note that this may not be per-flush if a longer running transaction is ongoing."""    def after_rollback(self, session):        """Execute after a rollback has occured.        Note that this may not be per-flush if a longer running transaction is ongoing."""    def before_flush(self, session, flush_context, instances):        """Execute before flush process has started.        `instances` is an optional list of objects which were passed to the ``flush()``        method.        """    def after_flush(self, session, flush_context):        """Execute after flush has completed, but before commit has been called.        Note that the session's state is still in pre-flush, i.e. 'new', 'dirty',        and 'deleted' lists still show pre-flush state as well as the history        settings on instance attributes."""    def after_flush_postexec(self, session, flush_context):        """Execute after flush has completed, and after the post-exec state occurs.        This will be when the 'new', 'dirty', and 'deleted' lists are in their final        state.  An actual commit() may or may not have occured, depending on whether or not        the flush started its own transaction or participated in a larger transaction.        """class SessionTransaction(object):    """Represents a Session-level Transaction.    This corresponds to one or more [sqlalchemy.engine#Transaction]    instances behind the scenes, with one ``Transaction`` per ``Engine`` in    use.    Direct usage of ``SessionTransaction`` is not necessary as of    SQLAlchemy 0.4; use the ``begin()`` and ``commit()`` methods on    ``Session`` itself.    The ``SessionTransaction`` object is **not** threadsafe.    """    def __init__(self, session, parent=None, autoflush=True, nested=False):        self.session = session        self._connections = {}        self._parent = parent        self.autoflush = autoflush        self.nested = nested        self._active = True        self._prepared = False    is_active = property(lambda s: s.session is not None and s._active)        def _assert_is_active(self):        self._assert_is_open()        if not self._active:            raise exceptions.InvalidRequestError("The transaction is inactive due to a rollback in a subtransaction and should be closed")    def _assert_is_open(self):        if self.session is None:            raise exceptions.InvalidRequestError("The transaction is closed")    def connection(self, bindkey, **kwargs):        self._assert_is_active()        engine = self.session.get_bind(bindkey, **kwargs)        return self.get_or_add(engine)    def _begin(self, **kwargs):        self._assert_is_active()        return SessionTransaction(self.session, self, **kwargs)    def _iterate_parents(self, upto=None):        if self._parent is upto:            return (self,)        else:            if self._parent is None:                raise exceptions.InvalidRequestError("Transaction %s is not on the active transaction list" % upto)            return (self,) + self._parent._iterate_parents(upto)    def add(self, bind):        self._assert_is_active()        if self._parent is not None and not self.nested:            return self._parent.add(bind)        if bind.engine in self._connections:            raise exceptions.InvalidRequestError("Session already has a Connection associated for the given %sEngine" % (isinstance(bind, engine.Connection) and "Connection's " or ""))        return self.get_or_add(bind)    def get_or_add(self, bind):        self._assert_is_active()                if bind in self._connections:            return self._connections[bind][0]                if self._parent is not None:            conn = self._parent.get_or_add(bind)            if not self.nested:                return conn        else:            if isinstance(bind, engine.Connection):                conn = bind                if conn.engine in self._connections:                    raise exceptions.InvalidRequestError("Session already has a Connection associated for the given Connection's Engine")            else:                conn = bind.contextual_connect()        if self.session.twophase and self._parent is None:            transaction = conn.begin_twophase()        elif self.nested:            transaction = conn.begin_nested()        else:            transaction = conn.begin()                self._connections[conn] = self._connections[conn.engine] = (conn, transaction, conn is not bind)        return conn    def prepare(self):        if self._parent is not None or not self.session.twophase:            raise exceptions.InvalidRequestError("Only root two phase transactions of can be prepared")        self._prepare_impl()            def _prepare_impl(self):        self._assert_is_active()        if self.session.extension is not None and (self._parent is None or self.nested):            self.session.extension.before_commit(self.session)                if self.session.transaction is not self:            for subtransaction in self.session.transaction._iterate_parents(upto=self):                subtransaction.commit()                    if self.autoflush:            self.session.flush()                if self._parent is None and self.session.twophase:            try:                for t in util.Set(self._connections.values()):                    t[1].prepare()            except:                self.rollback()                raise                self._deactivate()        self._prepared = True        def commit(self):        self._assert_is_open()        if not self._prepared:            self._prepare_impl()                if self._parent is None or self.nested:            for t in util.Set(self._connections.values()):                t[1].commit()            if self.session.extension is not None:                self.session.extension.after_commit(self.session)        self.close()        return self._parent    def rollback(self):        self._assert_is_open()                if self.session.transaction is not self:            for subtransaction in self.session.transaction._iterate_parents(upto=self):                subtransaction.close()                if self.is_active:            for transaction in self._iterate_parents():                if transaction._parent is None or transaction.nested:                    transaction._rollback_impl()                    transaction._deactivate()                    break                else:                    transaction._deactivate()        self.close()        return self._parent        def _rollback_impl(self):        for t in util.Set(self._connections.values()):            t[1].rollback()        if self.session.extension is not None:            self.session.extension.after_rollback(self.session)    def _deactivate(self):        self._active = False    def close(self):        self.session.transaction = self._parent        if self._parent is None:            for connection, transaction, autoclose in util.Set(self._connections.values()):                if autoclose:                    connection.close()                else:                    transaction.close()        self._deactivate()        self.session = None        self._connections = None    def __enter__(self):        return self    def __exit__(self, type, value, traceback):        if self.session.transaction is None:            return

⌨️ 快捷键说明

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