pythonflaskflask-migrate

Should we use flask-migrate in the init_app function or separately in our run script?


I am reading through Grinberg's Flask Development 2nd ed., and I have a question about flask migrate & a "large app structure".

Previously, I had used migrate like any other extension, like

# __init__.py
...
from flask_migrate import Migrate

...

migrate = Migrate()

...
def create_app():
    app = Flask(__name__)
    ...
    migrate.init_app(app, db)
    ...
    return app

This is suggested in the Flask-Migrate docs, but I understand it is obviously not the only way to do it. And then I had an entrypoint script, or root-level application script, which I call with python run.py:

# root-level application script
from app import create_app

app = create_app()

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

In the Flask Web Development book however, which walks through the Flasky app, Miguel shows on page 93 a setup where migrate is actually imported and initialised with app and db in the root-level application script and NOT the app-level __init__.py file. What I mean is this:

flasky
├── app/
│   ├── api/
│   ├── auth/
│   ├── main/
│   ├── static/
│   ├── templates/
│   └── __init__.py  # App-level init script
├── migrations/
└── flasky.py  # Root-level application script

There is not an explanation as to why this approach was chosen. I was previously running my app by calling the root-level application script, not using the flask run CLI command. When I tried having migrate in this root level, it of course was not recognised because I had not exported FLASK_APP=run.py, so the flask CLI command was unaware of db or migrate. This means I would need to change how I run my application.

My question then is, what might be the reasoning for putting migrate in the root level app script vs in my __init__.py file's create_app() function? Given that Miguel has written the extension he has decided on this for a reason but I am not sure why this extension is treated differently. Could it be something to do with separating the database-related code away from the rest of the application code?

Sorry if this is not the right place, but I can't exactly make an issue on the flasky github because it is just a question and not an issue.


Solution

  • Both approaches are valid. The reason one may want to initialize Flask-Migrate separately is that conceptually this is an extension that only affects the CLI, unlike most other extensions which are used by the server while running. But this is a very minor distinction, these days I initialize it along with all other extensions.