1

Ive been going at this for several hours but im afraid I still don't gronk flask app context and how my app should be implemented with Blueprints.

Ive taken a look at the this and this and have tried a few different recommendations but there must be something wrong with my basic approach.

I have one 'main' blueprint setup under the following PJ structure:

 project/
    app/
        main/
            __init__.py
            routes.py
            forms.py
            helper.py
        admin/
        static/
        templates/
        __init__.py
        models.py

app/init.py:

from flask import Flask
from config import config

from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.bootstrap import Bootstrap

db = SQLAlchemy()
bootstrap = Bootstrap()


def create_app(config_version='default'):
    app = Flask(__name__)
    app.config.from_object(config[config_version])
    bootstrap.init_app(app)
    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    db.init_app(app)

    return app

app/main/init.py

from flask import Blueprint
main = Blueprint('main',__name__)

from . import routes, helper

app/main/helper.py

#!/usr/bin/env python
from . import main
from ..models import SKU, Category, db
from flask import current_app


def get_categories():
    cat_list = []
    for cat in db.session.query(Category).all():
        cat_list.append((cat.id,cat.category))
    return cat_list

Everything worked fine until I created the get_categoriesfunction in helpers.py to pull a dynamic list for a select form in app/main/forms.py. When I fireup WSGI, however, I get this error:

RuntimeError: application not registered on db instance and no application bound to current context 

It would appear the db referenced in helper is not associated with an app context but when I try to create one within the function, it has not worked.

What am I doing wrong and is there a better way to organize helper functions when using Blueprints?

Community
  • 1
  • 1
user2957824
  • 177
  • 1
  • 5
  • 15
  • In the helper file, why is db imported from ..models? You don't show that file here, so I don't know what it looks like. – Gohn67 Oct 22 '14 at 21:00

1 Answers1

2

Documentation on database contexts here here.

My first thought was that you weren't calling db.init_app(app), but was corrected in the comments.

In app/main/helper.py, you're importing the database via from ..models import SKU, Category, db. This database object will not have been initialized with the app that you've created.

The way that I've gotten around this is by having another file, a shared.py in the root directory. In that file, create the database object,

from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()

In your app/init.py, don't create a new db object. Instead, do

from shared import db
db.init_app(app)

In any place that you want to use the db object, import it from shared.py. This way, the object in the shared file will have been initialized with the app context, and there's no chance of circular imports (which is one of the problems that you can run into with having the db object outside of the app-creating file).

Celeo
  • 5,583
  • 8
  • 39
  • 41
  • He has that line in the `app.init.py` file. Is that the correct location? – Gohn67 Oct 22 '14 at 20:58
  • I've tried importing db from models and from app but neither work – user2957824 Oct 22 '14 at 21:08
  • @Celeo, I just tried created sharedpy as sugggested but still getting same message. Do your recommendation for init.py work with an app factory (thats currently what I have in place)? – user2957824 Oct 22 '14 at 21:29
  • Were you sure to update your imports to import from the shared instead of the models? If you miss one, you'll still get the error. – Celeo Oct 22 '14 at 21:41
  • @Celeo yup in `helper.py` now has `from ..shared import db` import – user2957824 Oct 22 '14 at 21:49
  • @user2957824 `models.py` as well? – Celeo Oct 22 '14 at 22:08
  • @Celeo yup: '.shared import db' – user2957824 Oct 22 '14 at 22:22
  • The other issue is likely to be that you are defining the form class in code imported by the `main_blueprint` - which means that `get_categories` is called when `main_blueprint` is imported - which means you are working outside of the app context. Simply call `get_categories` inside the view to set the categories (or use the `QuerySelectField` with a `query_factory` instead). – Sean Vieira Oct 23 '14 at 15:17