Quel est le modèle d'utilisation de session scoped recommandé dans une webapp sqlalchemy multithreaded?

j'écris une application avec python et sqlalchemy-0.7. Il commence par initialiser l'orm de sqlalchemy (en utilisant declarative) et ensuite il démarre un serveur web multithreaded - je suis en train d'utiliser web.py pour le prototypage rapide, mais cela pourrait changer à l'avenir. Je vais aussi ajouter d'autres" threads " pour les travaux programmés et ainsi de suite, probablement en utilisant d'autres threads python.

à partir de la documentation SA je comprends que je dois utiliser scoped_session() pour obtenir une session thread-local, donc mon web.py app. devrait ressembler à ça:

import web
from myapp.model import Session  # scoped_session(sessionmaker(bind=engine))
from myapp.model import This, That, AndSoOn
urls = blah...
app  = web.application(urls, globals())

class index:
    def GET(self):
        s = Session()
        # get stuff done
        Session().remove()
        return(stuff)

class foo:
    def GET(self):
        s = Session()
        # get stuff done
        Session().remove()
        return(stuff)

Est-ce le bon Moyen de gérer la session?

pour autant que je comprenne, je devrais obtenir une scoped_session à chaque méthode car cela me donnera une session locale de thread que je ne pourrais pas obtenir à l'avance (comme au niveau du module).

aussi, je devrais appeler .remove() ou .commit() ou quelque chose comme à chaque fin de méthode, sinon la session contiendra encore persistante objets et je ne pourrais pas interroger/accéder aux mêmes objets dans d'autres threads?

si ce modèle est le bon, il pourrait probablement être amélioré en l'écrivant une seule fois, peut-être en utilisant un décorateur? Un tel décorateur pourrait obtenir la session, invoquer la méthode et ensuite s'assurer de disposer la session correctement. Comment cela ferait-il passer la séance à la fonction décorée?

25
demandé sur Luke404 2011-04-05 01:51:54
la source

2 ответов

Oui, c'est la bonne façon.

Exemple:

Fiole microfram framework with Flacon de sqlalchemy l'extension fait ce que vous avez décrit. Il le fait aussi .supprimer () automatiquement à la fin de chaque requête HTTP (fonctions"view"), de sorte que la session est libérée par le thread courant. Appelle juste .commit() n'est pas suffisant, vous devez utiliser .supprimer.)(

lorsque je n'utilise pas de vue flasque, j'utilise habituellement un "avec" déclaration:

@contextmanager
def get_db_session():
    try:
        yield session
    finally:
        session.remove()

with get_db_session():
    # do something

Vous pouvez créer un décorateur.

Scoped session crée un pool de connexion DBMS, de sorte que cette approche sera plus rapide que l'ouverture/fermeture de session à chaque requête HTTP. Il fonctionne aussi bien avec les greenlets (gevent ou eventlet).

19
répondu HighCat 2012-07-18 22:26:25
la source

vous n'avez pas besoin de créer une session scopée si vous créez une nouvelle session pour chaque requête et que chaque requête est traitée par un seul thread.

Vous devez appeler s.commit() faire en attente objets persistantes, i.e. pour sauvegarder les modifications dans la base de données.

s.close().

2
répondu Denis Otkidach 2011-04-05 11:59:02
la source

Autres questions sur