Flask-Migrate: SQLAlchemy Schema Migrations Behind the flask db Command
SQLAlchemy database migrations for Flask applications using Alembic
At a glance
- What is it?
- Flask-Migrate wraps Alembic in a Flask extension and exposes migrations as flask db subcommands. It is a thin layer, and the thinness is both the appeal and the limit.
- Who is it for?
- Adopt Flask-Migrate if your application already uses Flask-SQLAlchemy and you want migration commands living next to the rest of your flask CLI, with the generated scripts committed to version control. Do not adopt it if you want migration autogeneration you never read: the README states that Alembic does not detect every model change, indexes in particular, so every migrate output needs editing.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 34 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap Flask-Migrate fills between Flask-SQLAlchemy models and a live database
Flask-SQLAlchemy lets you declare tables as Python classes. It does not give you a history of how those tables changed. Once an application is deployed, adding a column means writing DDL by hand and hoping every environment receives the same statement in the same order. Flask-Migrate exists to remove that manual step. It is an extension that handles SQLAlchemy database migrations for Flask applications using Alembic, and it presents the database operations as command-line arguments under the flask db command.
The audience is narrow and specific: teams running Flask with Flask-SQLAlchemy who want schema changes tracked as files in the same repository as the application code. If your project does not use Flask, or does not use SQLAlchemy through Flask-SQLAlchemy, the extension has nothing to attach to. Its declared dependencies in pyproject.toml are Flask >= 0.9, Flask-SQLAlchemy >= 1.0 and alembic >= 1.9.0, and that list describes the intended shape of a host application fairly precisely. The package requires Python >= 3.6.
How the flask db command, Alembic and the migrations folder fit together
The architecture is a delegation, not a reimplementation. Alembic does the schema diffing, script generation and version tracking. Flask-Migrate registers a CLI group on the Flask application and routes flask db subcommands into Alembic, passing the application's database configuration through. The README's example is the whole wiring: create the Flask app, create the SQLAlchemy object, then instantiate Migrate with both.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db)That single Migrate(app, db) call is where the coupling lives. It gives the extension the app for configuration and the db object for model metadata. Everything downstream is Alembic behaviour surfaced under a different name.
The data flow has three artifacts. The migrations folder holds the Alembic environment and the generated revision scripts. Each script carries upgrade and downgrade functions plus a revision identifier that chains it to its parent. The database itself holds a version table recording which revision is currently applied. flask db migrate compares model metadata against the database and writes a new script; flask db upgrade executes the pending scripts in order. The README is explicit that the migrations folder needs to be added to version control along with your other source files, and that the generated script likewise needs to be committed. That is the whole synchronisation mechanism: another system gets the same schema by refreshing the folder from source control and running upgrade.
Installing Flask-Migrate and running your first migration
Installation is a single pip command. The README gives it as pip install Flask-Migrate, and the package is also published on PyPI.
pip install Flask-MigrateBefore any flask db command works, the README states that the FLASK_APP environment variable must be set according to the Flask documentation. This is the most common stumbling block, because the error you get is about the application not being found, not about migrations. The README does not give an export line, so set FLASK_APP the way the Flask documentation describes for your shell.
With the application in place, initialise the migration environment. This adds a migrations folder to your application, which you then commit.
flask db initGenerate the first revision from your models. The README is direct about what comes next: the migration script needs to be reviewed and edited, as Alembic currently does not detect every change you make to your models, and indexes in particular are called out as undetectable.
flask db migrateApply it. Each time the models change, the README says to repeat the migrate and upgrade pair.
flask db upgradeTo see the full command surface, run flask db --help. The README does not enumerate the subcommands beyond init, migrate and upgrade, so that help output is the authoritative list for your installed version.
The autogenerated script is a draft, and Alembic will not tell you where it is wrong
This is the limitation that decides whether Flask-Migrate suits a team. The README states plainly that Alembic does not detect every change you make to your models, and names indexes as a specific blind spot. A generated script that omits an index still applies cleanly. There is no warning. You find out later, when a query is slow or a uniqueness constraint you believed existed does not.
The practical consequence is that flask db migrate produces a draft that a human must read. That is a workflow cost, not a defect, and it scales with how much your schema changes. A team that treats migrate output as final will accumulate drift between what the models declare and what the database enforces.
There is a second boundary. Flask-Migrate is tied to Flask-SQLAlchemy for model metadata. An application that uses plain SQLAlchemy with a hand-built session, or that manages multiple independent databases through separate metadata objects, does not map onto the single Migrate(app, db) wiring the README shows. The extension also inherits Alembic's linear revision chain: two branches generating revisions from the same parent need an explicit merge before upgrade will proceed, and the README does not cover that case at all.
Flask-Migrate against using Alembic directly
Alembic is the underlying tool, and reaching for it directly is the obvious alternative. The difference is not capability, since Flask-Migrate does not add migration features Alembic lacks. The difference is configuration and invocation.
With Alembic alone you write an alembic.ini, create an env.py that imports your application's metadata, and run commands as alembic revision, alembic upgrade and so on. You control exactly how the metadata is loaded, which matters when the application factory pattern makes importing the app non-trivial, or when several metadata objects need to be combined into one migration context. Flask-Migrate instead reads the application's configuration through the Flask app object, so the database URI comes from app.config rather than a separate ini file. That removes duplicated configuration, and it is the main reason to prefer it inside a Flask project.
The trade-off runs the other way too. The alembic.ini and env.py that Flask-Migrate generates are still there in the migrations folder and can be edited, but the extension's conventions shape what those files look like from the start. If your migration setup needs to diverge from the Flask-SQLAlchemy single-database assumption, you are working around the wrapper rather than with it, and using Alembic directly removes that friction.
Maintenance, version floor and what the MIT licence lets you do
The repository is not archived. The last push was on 2026-08-29, which is recent enough that the project is receiving changes. The most recent tagged release is v4.1.0 from 2025-01-10, and pyproject.toml reports the working version as 4.1.1.dev0, so development is happening between releases.
The upgrade cost is mostly Alembic's, not Flask-Migrate's. The dependency floor is alembic >= 1.9.0, and the extension's own surface is small enough that version bumps rarely require changes to your application code. What does require attention is the migration scripts themselves: they are your files, committed to your repository, and no package upgrade rewrites them. A long-lived project accumulates them, and the cost of a schema change is the cost of reviewing one more script.
The licence is MIT, declared both in the LICENSE file and in the pyproject.toml classifiers. That permits commercial use, modification and redistribution with the licence text retained. It is a permissive licence with no copyleft obligation on your application. This is a description of the terms as stated in the repository, not legal advice; the LICENSE file is the text that governs.
Funding is handled through individual sponsorship platforms listed in the README rather than a foundation or a company. That is worth knowing when you assess how the project sustains itself, since there is no vendor with a commercial interest in the migration path.
Editorial conclusion
Adopt Flask-Migrate if your application already uses Flask-SQLAlchemy and you want migration commands living next to the rest of your flask CLI, with the generated scripts committed to version control. Do not adopt it if you want migration autogeneration you never read: the README states that Alembic does not detect every model change, indexes in particular, so every migrate output needs editing. Before you start, confirm FLASK_APP is set, since the README says the init command will not work without it, and check that your installed alembic satisfies the >= 1.9.0 floor declared in pyproject.toml.
Frequently asked questions
How do I install Flask-Migrate?
Install it with pip install Flask-Migrate, as shown in the README. It pulls in Flask, Flask-SQLAlchemy and alembic, and requires Python 3.6 or later.
What is Flask-Migrate used for?
It handles SQLAlchemy database migrations for Flask applications using Alembic, exposing the database operations as command-line arguments under the flask db command. You use it to generate and apply schema changes as versioned scripts rather than editing the database by hand.
How do I use Flask-Migrate in a Flask app?
Create the Flask app and a Flask-SQLAlchemy object, then instantiate Migrate with both, as the README example does. After that, run flask db init once, then flask db migrate and flask db upgrade each time your models change.
What does Flask-Migrate do?
It handles SQLAlchemy database migrations for Flask applications using Alembic. The README describes the database operations as command-line arguments under the flask db command.
How do I run flask migrate?
Set the FLASK_APP environment variable as the Flask documentation describes, then use the flask db subcommands: flask db init to add the migrations folder, flask db migrate to generate a script, and flask db upgrade to apply it.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/miguelgrinberg-flask-migrate)