多线程使用SQLAlchemy

时间:2011-06-09 18:20:19

标签: python multithreading sqlalchemy

我想创建一个用Python编写的数据库应用程序编程接口,并使用SQLAlchemy(或任何其他数据库连接器,如果它被告知使用SQLAlchemy进行此类任务不是一个好方法)。该设置是在Linux或BSD上运行的MySQL服务器,以及在Linux或BSD机器上运行的Python软件(无论是外国还是本地)。

基本上我想要做的是为每个连接生成一个新线程,协议将是自定义的并且非常简单,尽管对于每个请求我想打开一个新事务(或者我已阅读的会话)然后我需要提交会话。我现在面临的问题是,另一个会话很可能同时从另一个连接发生。

我的问题是我应该怎样处理这种情况?

  • 我应该使用锁定,因此只能同时运行一个会话吗?
  • 会话实际上是线程安全的,我认为它们不是吗?
  • 有没有更好的方法来处理这种情况?
  • 是不是要走的路?

1 个答案:

答案 0 :(得分:46)

会话对象是线程安全的,但是线程本地From the docs:

  

Session对象完全被设计为以非并发方式使用,在多线程方面意味着”一次仅在一个线程中“。某些进程需要在适当的位置,以便多个线程的多个调用实际上不会获得同一个会话的句柄。我们将这个概念称为线程本地存储。“

如果您不想自己管理线程和会话,SQLAlchemy有ScopedSession对象来处理这个问题:

  

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

     

使用这种技术,ScopedSession提供了一种快速且相对简单的方法,可以在应用程序中提供可以安全地从多个线程调用的单个全局对象。

请参阅Contextual/Thread-local Sessions中的示例,了解如何设置自己的线程安全会话:

# set up a scoped_session
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker

session_factory = sessionmaker(bind=some_engine)
Session = scoped_session(session_factory)

# now all calls to Session() will create a thread-local session
some_session = Session()

# you can now use some_session to run multiple queries, etc.
# remember to close it when you're finished!
Session.remove()