简体   繁体   中英

Atomic transactions using Flask before_request and after_request

I am trying to make py2neo transactions with Flask atomic by means of using before_request to start a transaction and after_request to commit or rollback, depending on the response status code.

This is my code:

from flask import Flask, request, app, g
from flask_restful import Resource, Api, abort
from werkzeug.wrappers import Request
from py2neo import Graph
import models

app = Flask(__name__)
api = Api(app)

def get_db():
    return Graph(password="secret")

graph = get_db()
tx = None

@app.before_request
def before_request():
    tx = graph.begin()

@app.after_request
def after_request(response):
    if response.status_code >= 400:
        tx.rollback()
    else:
        tx.commit() # Error line

The problem is that modifications to module variable tx made on before_request seem not to be noticeable by after_request , so I get this error:

AttributeError: 'NoneType' object has no attribute 'commit'

I found a solution. All I had to do is to use flask g object to store tx so it can be available for all methods called along the request:

from flask import Flask, request, app, g
from flask_restful import Resource, Api, abort
from werkzeug.wrappers import Request
from py2neo import Graph
import models

app = Flask(__name__)
api = Api(app)

def get_db():
    return Graph(password="SteppenWolf1")

graph = get_db()

@app.before_request
def before_request():
    g.tx = graph.begin()

@app.after_request
def after_request(response):
    tx = g.get('tx')
    if response.status_code >= 400:
        tx.rollback()
    else:
        tx.commit()

    return response

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM