2011-07-16 7 views
0

Voici le code correspondant de mes sites __init__.pyEssayer d'obtenir la tempête ORM à travailler avec Pyramid mais je vais avoir des problèmes avec des fils

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() 

Voici mon 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) 

Et voici mes utilisateurs modèle:

def create_account(username, password): 

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

    DBSession.add(user) 
    DBSession.flush() 

D'après ce que j'ai lu de la tempête faire documentation, tout est correct. Le problème est, lorsque la fonction est appelée create_account de mon avis appelable, je reçois l'exception suivante jeté:

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 

j'étais même pas au courant Pyramid a été enfilait l'application:/

Comment puis-je corriger ce?

Répondre

1

Le serveur Web que vous utilisez est multithread, pas Pyramid lui-même. Il est plus sûr de penser à votre application en termes de gestion des demandes. Fondamentalement, vous aurez une demande par thread à un moment donné, de sorte que chaque demande active doit utiliser une connexion différente à la base de données. Ceci est géré trivialement en utilisant le scoped_session de SQLAlchemy, mais vous pouvez également le faire d'une manière similaire à la façon dont this Pyramid tutorial le fait avec des connexions SQLite brutes.

L'idée de base ici est qu'il établit une nouvelle connexion à la base de données dans un abonné NewRequest, donc vous êtes assuré qu'il n'y aura pas de problèmes de threading de partager des connexions entre les demandes. Vous pouvez également utiliser ce paradigme avec un pool de connexion que je suis sûr que ORM décent vous fournit.

Mise à jour Après avoir examiné plus attentivement la tempête, je ne vois pas une tonne de soutien à la mise en commun de connexion, mais il y a le paquet ZStorm qui intégrera la tempête avec le transaction manager que Pyramid utilise. Cela met en œuvre des mécanismes de mise en commun qui vous faciliteraient la vie.

0
global DBSession 

est votre problème. Le manuel de Storm est très explicite à propos de this.

Vous devez utiliser un stockage local. threading.local est la réponse:

import threading 
tlocal = threading.local() 

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

#etc 
Questions connexes