user956424
user956424

Reputation: 1609

how to use after_request in flask to close database connection and python?

How to use after_request decorator to close a connection after the request is processed? I use the before_request for opening the connection for each api request as follows: Using sqlalchemy core 1.0.8 and postgresql 9.5:

#engine = create_engine(os.environ.get("DB_URL"))
DB_URL="postgresql://mowner:passwd@localhost/mydb"

@app.before_request
def before_request():
    engine = create_engine(DB_URL, strategy='threadlocal')
    conn = engine.connect()


@app.after_request
def after_request(conn):
     if conn is not None:
         print 'closing connection'
         conn.close()

sample api call:

@app.route('/api/v1.0/categories', methods=['GET'])
def categories_list():
    '''
    Return categories list
    '''
    if 'id' in session:
        categories_list = []
        s = select([categories])
        rs = conn.execute(s)
        if rs.rowcount > 0:
            for r in rs:
                categories_list.append(dict(r))
            rs.close()
        # print 'this doesnt execute'
        return jsonify({'categories list': categories_list}), 200

    return jsonify({'message': "UNAUTHORIZED"}), 401

The views are api calls which only return a list of objects, added, or edit object and a message. How exactly to pass the connection object to the after_request decorator? I couldn't really follow the documentation Exact code will help me.

Upvotes: 6

Views: 11576

Answers (1)

Sohaib Farooqi
Sohaib Farooqi

Reputation: 5666

You can use flask.g to refer to create a global db connection object and use it everywhere

from flask import Flask, g

#engine = create_engine(os.environ.get("DB_URL"))
DB_URL="postgresql://mowner:passwd@localhost/mydb"

@app.before_request
def before_request():
   engine = create_engine(DB_URL, strategy='threadlocal')
   conn = engine.connect()
   g.db = conn

Then use connection in your route like this

@app.route('/api/v1.0/categories', methods=['GET'])
def categories_list():
    '''
    Return categories list
    '''
    if 'id' in session:
        categories_list = []
        s = select([categories])
        rs = g.db.execute(s) # change in variable
        if rs.rowcount > 0:
           for r in rs:
             categories_list.append(dict(r))
        rs.close()
        # print 'this doesnt execute'
       return jsonify({'categories list': categories_list}), 200
    return jsonify({'message': "UNAUTHORIZED"}), 401

Then finally close it like this:

@app.after_request
def after_request(response):
    if g.db is not None:
        print 'closing connection'
        g.db.close()
     return response

Upvotes: 6

Related Questions