Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using flask-migrate with flask-script and application factory

I'm building flask application and decided to try application factory approach this time, but got into trouble with flask-migrate and can't figure out simple solution.

Please note that I want to pass config 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 create migrate instance and add command to the manager:

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

but app instance is not created yet, so it fails

I know I can pass config in environment variable and create application before creating manager instance, but how to do it using manager options?

like image 215
ETK Avatar asked Apr 26 '15 02:04

ETK


1 Answers

When you use a --config option you have to use an application factory function as you know, as this function gets the config as an argument and that allows you to create the app with the right configuration.

Since you have an app factory, you have to use the deferred initialization for all your extensions. You instantiate your extensions without passing any arguments, and then in your app factory function after you create the application, you call init_app on all your extensions, passing the app and db now that you have them.

The MigrateCommand is completely separate from this, you can add that to the Manager without having app and db instances created.

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 however 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
like image 111
Miguel Avatar answered Oct 04 '22 09:10

Miguel