【问题标题】:Trying to get the Storm ORM to work with Pyramid but I'm having troubles with threads试图让 Storm ORM 与 Pyramid 一起工作,但我遇到了线程问题
【发布时间】:2011-07-16 02:55:15
【问题描述】:

这是来自我的网站__init__.py的相关代码

from site.models import initialise_sql

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application """

    initialise_sql(settings['database.url'])

    return config.make_wsgi_app()

这是我的models/__init__.py

from storm.locals import *

from datetime import datetime

DBSession = None

class Tables:
    """ A simple namespace for all the table objects in our database """

    class Users(object):

        __storm_table__ = 'users'

        user_id      = Int(primary=True)
        username     = RawStr()
        password     = RawStr()
        date_created = DateTime(default=datetime.now())

def initialise_sql(db_uri):
    """ Initialise the database """

    global DBSession

    database  = create_database(db_uri)
    DBSession = Store(database)

这是我的用户模型:

def create_account(username, password):

    user = Tables.Users()
    user.username = username
    user.password = password

    DBSession.add(user)
    DBSession.flush()

根据我对 Storm 文档的阅读,这一切都是正确的。问题是,当 create_account 从我的视图可调用函数中调用时,我得到以下异常:

ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id -1220417856 and this is thread id -1239418000

我什至不知道 Pyramid 正在线程化应用程序:/

我该如何解决这个问题?

【问题讨论】:

    标签: python orm pylons pyramid storm-orm


    【解决方案1】:

    您使用的网络服务器是多线程的,而不是 Pyramid 本身。从处理请求的角度考虑您的应用程序会更安全。基本上,在任何给定时间点,每个线程都会有一个请求,因此每个活动请求都应该使用与数据库的不同连接。使用 SQLAlchemy 中的 scoped_session 可以轻松处理此问题,但您也可以采用类似于 this Pyramid tutorial 处理原始 SQLite 连接的方式来执行此操作。

    这里的基本思想是它在NewRequest 订阅者中与数据库建立新连接,因此可以保证跨请求共享连接不会出现任何线程问题。您还可以将此范例与连接池一起使用,我相信任何体面的 ORM 都可以为您提供。

    更新 在仔细查看 Storm 之后,我没有看到对连接池的大量支持,但是 ZStorm 包将 Storm 与 Pyramid 使用的transaction manager 集成在一起。这确实实现了一些池化机制,让您的生活更轻松。

    【讨论】:

      【解决方案2】:
      global DBSession
      

      是你的问题。 Storm 手册对this 非常明确。

      您需要使用线程本地存储。 threading.local 就是答案:

      import threading
      tlocal = threading.local()
      
      def initialise_sql(db_uri):
          global tlocal
          db = create_database(db_uri)
          tlocal.dbsession = Store(db)
      
      #etc
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多