试图让Storm ORM与Pyramid一起工作,但我遇到线程问题

时间:2011-07-16 02:55:16

标签: python orm pylons pyramid storm-orm

以下是我的网站__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正在线程化应用程序:/

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

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

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

更新在仔细查看Storm之后,我看不到大量支持连接池,但是有一个ZStorm软件包可以将Storm与transaction manager金字塔集成在一起使用。这确实实现了一些池化机制,使您的生活更轻松。

答案 1 :(得分:0)

global DBSession

是你的问题。风暴手册非常清楚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