0

これが私のウェブサイトからの関連コードです__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がアプリケーションをスレッド化していることに気づいていませんでした:/

どうすればこれを修正できますか?

4

2 に答える 2

1

使用している Web サーバーはマルチスレッドであり、Pyramid 自体ではありません。リクエストの処理という観点からアプリケーションについて考える方が安全です。基本的に、任意の時点でスレッドごとに 1 つのリクエストがあるため、アクティブなリクエストごとにデータベースへの異なる接続を使用する必要があります。これは SQLAlchemy の を使用して簡単に処理されますが、この Pyramid チュートリアルが生の SQLite 接続でscoped_session行うのと同様の方法でこれを行うこともできます。

ここでの基本的な考え方は、NewRequestサブスクライバーでデータベースへの新しい接続を確立することです。そのため、リクエスト間で接続を共有することによるスレッドの問題が発生しないことが保証されます。このパラダイムを接続プールで使用することもできます。適切なORMが提供していると確信しています。

更新Storm をより注意深く調べたところ、接続プーリングのサポートはそれほど多くはありませんが、Stormを Pyramid が使用するトランザクション マネージャーと統合する ZStorm パッケージがあります。これは、あなたの人生を楽にするいくつかのプーリングメカニズムを実装します.

于 2011-07-16T20:57:37.723 に答える
0
global DBSession

あなたの問題です。Storm のマニュアルでは、これについて非常に明確に説明されています。

スレッド ローカル ストレージを使用する必要があります。threading.local が答えです:

import threading
tlocal = threading.local()

def initialise_sql(db_uri):
    global tlocal
    db = create_database(db_uri)
    tlocal.dbsession = Store(db)

#etc
于 2011-07-21T13:44:38.720 に答える