2011-07-16 17 views
0

とのトラブルを抱えている。ここに私のウェブサイトから該当するコード__init__.pyはピラミッドで動作するように嵐のORMを取得しようとしているが、私はスレッド

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 

私はピラミッドがアプリケーションをスレッドしても認識されませんでした:/

私はどのように修正することができますこの?

答えて

1

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

ここでの基本的な考え方は、NewRequestサブスクライバに新しいデータベース接続を確立するということです。したがって、要求を渡って接続を共有することによるスレッドの問題は発生しません。また、このパラダイムを接続プールと共に使用することもできます。これは、まともなORMがあなたに供給していると確信しています。

更新より慎重に嵐を見た後、私は、接続プーリングのサポートのトンを見ていないが、ピラミッドが使用するtransaction managerで嵐を統合するZStormパッケージがあります。これはあなたの人生を容易にするいくつかのプールメカニズムを実装します。

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 
関連する問題