pjdavis
pjdavis

Reputation: 345

Accessing the same flask-sqlalchemy queryset across Flask routes

This is the code I have written so far in my views.py file:

from flask import Flask, jsonify
from app import db
from models import Sites

app = Flask(__name__)
app.config.from_pyfile('config.py')
db.init_app(app)

@app.route('/site-list')
def site_list():
    site_table = Sites.query.all()
    return jsonify({a.name: a.id for a in site_table})

@app.route('/site-geo')
def site_geo():
    site_geo = Sites.query.all()
    return jsonify({a.name: a.lat + ", " + a.long for a in site_geo})

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=8080, passthrough_errors=True)

So I believe that by using the init_app() method of db (a flask-sqlalchemy object) I have created a new Flask instance assigned to app. The object db is imported from app.py (whose purpose in to generate data and insert it into the database). app.py and db.py share the same config.py file which specifies the database URI.

As you can see I have repeated myself within the two Flask routes with Sites.query.all(). The code currently works fine in returning the desired JSON response. However, when I try to move the assignment of Sites.query.all() from within a function/Flask route to outside of the Flask route, it gives a Runtime error: application not registered on db instance and no application bound to current context.

How can I the access the queryset across all my flask routes, so that I don't have to keep repeating myself?

Upvotes: 1

Views: 1641

Answers (1)

Tim Darbyshire
Tim Darbyshire

Reputation: 31

If you are worried about repeating yourself one option is to add this query as a classmethod for the Sites model like below:

@classmethod
def get_all(cls):
    sites_all = Sites.query.all()
    return sites_all

And then in your views.py you can run Sites.get_all(), you could expand on this to pass a parameter to the method to perform your formatting also.

If you are worried about querying the database twice then you could save the query set in session memory and then retrieve it in each route that is required, although I don't know whether this would give an advantage at all.

To save:

session['sites_all'] = sites_all

To retrieve:

session.pop('sites_all', None)

Upvotes: 1

Related Questions