2017-04-25 1 views
0

Le code suivant lance une DatabaseSessionIsOver exception, comme décrit dans this post:Gérer la session Poney à Pyramid

Je résolu le problème en utilisant return render_to_response('templates/home.jinja2', {'x': x}), qui est l'équivalent Pyramide du render_template() suggéré dans le poste mentionné ci-dessus.

Tout fonctionne bien, mais je pense qu'il y a une meilleure solution: je pense que je devrais dire à Pyramid de gérer la session Pony.

Est-ce possible?

Comment faire?

Répondre

1

Votre problème est que vous renvoyez l'objet géré x à partir de la vue, puis la session orm est fermée avant que la réponse de la vue ne soit affichée. Vous souhaitez que la session enveloppe une plus grande partie du cycle de vie de la demande afin que vos objets gérés restent en vie plus longtemps. Pour quelque chose comme une session de base de données, une interpolation est vraiment la meilleure façon de gérer cela, mais il existe d'autres moyens tels qu'une combinaison d'une propriété de requête request.pony_session et un callback fini qui peut fermer la session. Par exemple (désolé, je ne sais pas vraiment de api de poney de sorte que vous devez remplir les méthodes actuelles):

def get_pony_session(request): 
    session = ... # load a pony session somehow 
    def cleanup(request): 
     try: 
      if request.exception: 
       session.abort() 
      else: 
       session.commit() 
     finally: 
      session.close() 
    request.add_finished_callback(cleanup) 
    return session 
config.add_request_method(get_pony_session, 'pony_session', reify=True) 

Vous pouvez voir comment la pyramide fait des choses avec l'interpolation de pyramid_tm et la cookiecutter de l'alchimie comme il est vraiment la meilleure approche pour ce problème. Vous pourriez même écrire une petite enveloppe pour accrocher la session de pony dans pyramid_tm si vous le vouliez. Pour ce faire, vous écrivez un gestionnaire de données [1, 2] qui gère la session pony et joint la transaction pyramid_tm (cette transaction est "virtuelle" et n'a rien à voir avec une base de données particulière) et une propriété de requête:

class PonySessionManager: 
    def __init__(self, session): 
     self.session = session 

    def tpc_abort(self, txn): 
     self.session.abort() 

    def tpc_commit(self, txn): 
     self.session.commit() 

    def tpc_finish(self, txn): 
     self.session.close() 

def get_pony_session(request): 
    session = ... # load a pony session somehow 
    manager = PonySessionManager(session) 
    # join the manager to the pyramid_tm transaction via join() 
    txn = request.tm.get() 
    txn.join(manager) 
    return manager 

config.add_request_method(get_pony_session, 'pony_session', reify=True) 

Notez que le gestionnaire de données est un peu plus simple que ce qui est requis, mais ce n'est pas difficile. À la fin de la journée, vous trouverez probablement le diagramme suivant [2] utile pour comprendre la pyramide et les crochets que vous pouvez utiliser. Il est rare que vous vouliez seulement envelopper la vue elle-même et pas plus du pipeline.

[1] http://zodb.readthedocs.io/en/latest/transactions.html

[2] http://transaction.readthedocs.io/en/latest/datamanager.html

[3] http://docs.pylonsproject.org/projects/pyramid/en/1.8-branch/narr/router.html