以下是我的网站__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正在线程化应用程序:/
我该如何解决这个问题?
答案 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