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
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)
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.