【问题标题】:Multi-threaded use of SQLAlchemySQLAlchemy的多线程使用
【发布时间】:2011-09-11 22:46:08
【问题描述】:

我想制作一个用 Python 编写的数据库应用程序编程接口,并使用 SQLAlchemy(或任何其他数据库连接器,如果被告知使用 SQLAlchemy 执行此类任务不是好方法)。设置是在 Linux 或 BSD 上运行的 MySQL 服务器和在 Linux 或 BSD 机器(外部或本地)上运行的 Python 软件。

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

我的问题是我应该如何处理这种情况?

  • 我是否应该使用锁,以便只能同时运行一个会话?
  • 会话实际上是线程安全的,我认为它们不是线程安全的吗?
  • 有没有更好的方法来处理这种情况?
  • 线程化的方式不可行吗?

【问题讨论】:

    标签: python multithreading sqlalchemy


    【解决方案1】:

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

    Session 对象完全设计为以非并发方式使用,就多线程而言,这意味着“一次只能在一个线程中”.. 某些进程需要确保跨多个线程的多次调用实际上不会获得同一个会话的句柄。我们将此概念称为线程本地存储。”

    如果您不想自己做管理线程和会话的工作,SQLAlchemy 有 ScopedSession 对象来帮您处理:

    ScopedSession 对象默认使用threading.local() 作为存储,因此为所有调用ScopedSession 注册表的人维护一个Session,但仅限于单个线程的范围内。在不同线程中调用注册表的调用者会获得该其他线程本地的 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()
    

    【讨论】:

    • 不是session.remove()
    • @AllanRuin:如果session 是指提供的示例中的some_session,则不。 session 对象没有 remove 方法。在这种情况下,Session 是一个 scoped_session 对象。它的remove 方法识别当前的session 并在丢弃它之前调用它的close 方法。解释in the docs
    • 引擎怎么样?您是否在主线程中保留一个全局引擎?还是每个线程创建一个引擎?
    • @culix:介意在您的答案中添加有关引擎的详细信息吗?我一直在阅读这方面的内容,并且在并行化时,您必须确保 每个进程 只存在一个引擎。对于多线程这很容易,对于多处理可能需要更多的工作。见docs.sqlalchemy.org/en/latest/core/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 2012-03-26
    相关资源
    最近更新 更多