Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflecting tables with Flask-SQLAlchemy raises RuntimeError: application not registered

I have an SQLite database to manage user logins, along with an existing MySQL database. I added the MySQL database to the Flask-SQLAlchemy SQLALCHEMY_BINDS config. When I try to reflect the tables, I get the following error:

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

How do I correctly reflect the tables?

__init__.py:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from config import config

db = SQLAlchemy()

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)

    db.init_app(app)

    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    return app

manage.py:

from myapp import create_app
from flask.ext.migrate import Migrate, MigrateCommand

app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()

models.py:

from . import db, login_manager

db.Model.metadata.reflect(db.engine)

class Calls(db.Model):
    __table__ = db.Model.metadata.tables['Calls2']
    __bind_key__ = 'calls'

    def __repr__(self):
        return self.test1
Traceback (most recent call last):
  File "./manage.py", line 6, in <module>
    from app.models import User, Role, Permission
  File "/home/ilias/Desktop/client-reporting/app/models.py", line 9, in <module>
    db.Model.metadata.reflect(db.engine)
  File "/home/ilias/Desktop/client-reporting/local/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 780, in engine
    return self.get_engine(self.get_app())
  File "/home/ilias/Desktop/client-reporting/local/lib/python2.7/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
like image 768
Galil Avatar asked Mar 31 '16 15:03

Galil


1 Answers

You can't perform operations on the database until the extension has been initialized with the app, which won't happen until the app factory function is used. Move the reflect call inside the factory, and use db.reflect, which reflects all the binds, not just the main one.

def create_app():
    app = Flask(__name__)
    ...

    db.init_app(app)
    db.reflect(app=app)
    # you could also push an app context instead of passing app
    # with app.app_context():
    #     db.reflect()

    ...
    return app

Since the models are imported as part of the views, which are only imported inside the factory, the metadata will contain the reflected tables by the time the models are defined.

like image 189
davidism Avatar answered Oct 13 '22 00:10

davidism