When scattering Flask Models, RuntimeError: 'application not registered on db' was raised

I am re-factoring my Flask application by scattering the models, blueprints but I am having a runtime error.

    def create_app():
        app = flask.Flask("app")
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
        app.register_blueprint(api)
        db.init_app(app)
        db.create_all()
        return app

I have the following problem(the sample project are hosted here: https://github.com/chfw/sample):

    Traceback (most recent call last):
      File "application.py", line 17, in <module>
        app = create_app()
      File "application.py", line 12, in create_app
        db.create_all()
      File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 856, in create_all
        self._execute_for_all_tables(app, bind, 'create_all')
      File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 836, in _execute_for_all_tables
        app = self.get_app(app)
      File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 809, in get_app
        raise RuntimeError('application not registered on db 
               'RuntimeError: application not registered on db 
                instance and no application bound to current context

I did a research on this topic. The re-factoring is suggested here:

Flask-SQLAlchemy import/context issue

The same problem was raised here:

http://flask.pocoo.org/mailinglist/archive/2010/8/30/sqlalchemy-init-app-problem/#b1c3beb68573efef4d6e571ebc68fa0b

And the above thread(2010) suggested a hack like this:

        app.register_blueprint(api)
        db.app=app #<------------<<
        db.init_app(app)

Did anyone know how to do this properly? How did you solve it?

Thanks

This has to do with Flask's application context. When initialized with db.init_app(app), Flask-SQLAlchemy doesn't know which app is the "current" app (remember, Flask allows for multiple apps in the same interpreter). You could have multiple apps using the same SQLAlchemy instance in the same process, and Flask-SQLAlchemy would need to know which is the "current" one (due to Flask's context local nature of everything).

If you need to do this during runtime, you must explicitly say which app is the "current" app for all calls. You can do this by changing your code to use a with app.app_context() block:

    def create_app():
        app = flask.Flask("app")
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
        app.register_blueprint(api)
        db.init_app(app)
        with app.app_context():
            # Extensions like Flask-SQLAlchemy now know what the "current" app
            # is while within this block. Therefore, you can now run........
            db.create_all()

        return app

If you are writing a standalone script that needs the app context, you can push the context at the beginning rather than putting everything in a with block.

    create_app().app_context().push()

If you write a command for Flask's cli the command will automatically have access to the context.

From: stackoverflow.com/q/19437883