我是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实例如何是本地的?
答案 0 :(得分:0)
因此,我们上面的scoped_session用法示例(其中跨多个调用维护相同的Session对象)表明需要一些进程,以便跨多个线程的多个调用实际上不会获得同一会话的句柄。我们称之为概念线程本地存储,这意味着使用了一个特殊对象,它将为每个应用程序线程维护一个不同的对象。 Python通过threading.local()构造提供了这个。
因此即使我没有想出如何从给定会话中获取当前线程的pid
,threading
模块也用于将会话链接到线程。特别是,可以查看会话的hash key
session.hash_key
在问题的示例中测试Session()
在两次调用中提供相同的会话,当且仅当两者都在同一个线程中进行时。
总而言之,只要每个请求都由自己的线程处理,会话就会正确地链接到请求。