SQLAlchemy:如何将作用域会话绑定到请求

时间:2016-10-30 12:07:38

标签: python session sqlalchemy

我是sqlalchemy的新手,似乎我仍然怀念几个基本概念。我想使用sqlalchemy来处理多线程Web应用程序中的数据库交互。

所以我从

开始
import sqlalchemy
from sqlalchemy                 import create_engine
from sqlalchemy.orm             import sessionmaker, scoped_session

engine          = create_engine('mysql://mydb')
session_factory = sessionmaker( autocommit  = False,
                                autoflush   = False,
                                bind        = engine )
Session         = scoped_session(session_factory)

我使用处理请求的MoinMoin wiki,因此我有一个包含请求的对象macro.request

我现在在某个班级有一个方法,比如说

def do_sth():
    session = Session()
    # use the session to get some data from the db
  

我在哪里以及如何告诉Session对象链接到哪个请求?

阅读Multi-threaded use of SQLAlchemy,它说

  

默认情况下,ScopedSession对象使用[threading.local()]作为存储,因此为所有调用ScopedSession注册表的人维护单个会话,但仅限于单个线程的范围内。在另一个线程中调用注册表的调用者获得一个本地其他线程的Session实例。

所以"在另一个线程中调用注册表的调用者获得一个本地其他线程的Session实例。"

  

如果我从未告诉它链接到哪个请求,那么Session实例如何是本地的?

1 个答案:

答案 0 :(得分:0)

SQLAlchemy documentation

  

因此,我们上面的scoped_session用法示例(其中跨多个调用维护相同的Session对象)表明需要一些进程,以便跨多个线程的多个调用实际上不会获得同一会话的句柄。我们称之为概念线程本地存储,这意味着使用了一个特殊对象,它将为每个应用程序线程维护一个不同的对象。 Python通过threading.local()构造提供了这个。

因此即使我没有想出如何从给定会话中获取当前线程的pidthreading模块也用于将会话链接到线程。特别是,可以查看会话的hash key

session.hash_key

在问题的示例中测试Session()在两次调用中提供相同的会话,当且仅当两者都在同一个线程中进行时。

总而言之,只要每个请求都由自己的线程处理,会话就会正确地链接到请求。