2017-04-25 3 views
0

Der folgende Code führt eine DatabaseSessionIsOver Ausnahme, wie in this post beschrieben:verwalten Pony-Sitzung in Pyramid

ich das Problem mit return render_to_response('templates/home.jinja2', {'x': x}) gelöst, die die Pyramide Äquivalent des render_template() ist in der Post oben erwähnt vorgeschlagen.

Alles funktioniert gut, aber ich denke, es gibt eine bessere Lösung: Ich denke, ich sollte Pyramid sagen, die Pony-Sitzung zu verwalten.

Ist es möglich?

Wie mache ich das?

Antwort

1

Ihr Problem besteht darin, dass Sie das verwaltete Objekt x aus der Ansicht zurückgeben und dann die ORM-Sitzung geschlossen wird, bevor die Antwort der Ansicht gerendert wird. Sie möchten, dass die Sitzung einen größeren Teil des Anforderungslebenszyklus umschließt, damit Ihre verwalteten Objekte länger am Leben bleiben. Für so etwas wie eine Datenbanksitzung ist ein Tween der beste Weg, dies zu handhaben, aber es gibt auch andere Möglichkeiten, wie eine Kombination aus einer Anfrageeigenschaft request.pony_session und einem fertigen Rückruf, der die Sitzung schließen kann. Zum Beispiel (sorry ich weiß nicht wirklich Ponys api, so dass Sie in den eigentlichen Methoden füllen):

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) 

können Sie sehen, wie Pyramide tut Dinge mit dem pyramid_tm Tweens und der Alchemie cookie wie es wirklich ist der beste Ansatz für dieses Problem. Du könntest sogar einen kleinen Wrapper schreiben, um die Pony-Session in pyramid_tm zu bringen, wenn du willst. Um dies zu tun, schreiben Sie grundsätzlich einen Datenmanager [1, 2], der die Pony-Sitzung verwaltet und sich der Transaktion pyramid_tm anschließt (diese Transaktion ist "virtuell" und hat nichts mit einer bestimmten Datenbank zu tun) und eine Anfrageeigenschaft:

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) 

Beachten Sie, dass Datenmanager ein wenig vereinfachter ist als das, was erforderlich ist, aber es ist nicht schwierig.

Am Ende des Tages finden Sie wahrscheinlich das folgende Diagramm [2] hilfreich zu verstehen, Pyramide und welche Haken Sie verwenden können. Es ist selten, dass Sie nur die Ansicht selbst und nicht mehr der Pipeline umbrechen möchten.

[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

Verwandte Themen