Using flask-migrate with flask script and app factory

I'm building a flask app and decided to try a factory app this time, but got into a flask-migrate problem and can't find an easy solution.

Please note that I want to pass the configuration location as an option to the script

manage.py:

manager = Manager(create_app)
manager.add_option("-c", "--config", dest="config_module", required=False)

      

then I need to instantiate the transfer and add the command to the manager:

with manager.app.app_context():
    migrate = Migrate(current_app, db)
    manager.add_command('db', MigrateCommand)

      

but the app hasn't been instantiated yet, so it fails

I know I can pass the configuration in an environment variable and create the application before instantiating the dispatcher, but how do I do this using the manager options?

+6


source to share


1 answer


When you use --config

you must use the application factory function as you know, since this function takes the configuration as an argument and this allows you to create the application with the correct configuration.

Since you have an application factory, you should use lazy initialization for all your extensions. You create your extensions without passing arguments, and then in your application factory function, after creating your application, you call init_app

for all your extensions, passing the application and database now that you have them.

MigrateCommand

completely decoupled from this, you can add this in Manager

without instantiating app and db.

Example:



manage.py:

from app import create_app
from flask_migrate import MigrateCommand, Manager

manager = Manager(create_app)
manager.add_option("-c", "--config", dest="config_module", required=False)
manager.add_command('db', MigrateCommand)

      

app.py (or whatever your app factory module is called)

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

db = SQLAlchemy()
migrate = Migrate()

def create_app(config):
    app = Flask(__name__)
    # apply configuration
    # ...

    # initialize extensions
    db.init_app(app)
    migrate.init_app(app, db)

    return app

      

+15


source







All Articles