Reputation: 1416
I have a flask-appbuilder
(FAB) project and I would like to use flask-migrate
to handle db migrations. However FAB creates the db on its own beforehand, so that flask-migrate
cannot compute the migrations
I'm aware of this example and of this issue on FAB's repository, however I wasn't able to use them to solve the problem.
This is a minimal app to show the problem.
# app.py
from flask import Flask
from flask_appbuilder import AppBuilder, SQLA
from flask_migrate import Migrate
import os
from flask_appbuilder import Model
from sqlalchemy import Column, Integer
class Config():
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
db = SQLA()
migrate = Migrate()
appbuilder = AppBuilder()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
migrate.init_app(app, db)
with app.app_context():
appbuilder.init_app(app, db.session)
appbuilder.post_init()
return app
class MyTable(Model):
__tablename__ = "my_table"
id = Column(Integer, primary_key=True)
mycol = Column(Integer)
if __name__ == "__main__":
app = create_app()
app.run()
It can be tested in a virtual environment with the following requirements.txt
:
flask-appbuilder==3.1.0
SQLAlchemy==1.3.24
flask-migrate
By issuing
export FLASK_APP=app.py
flask db init
flask db migrate
the output reads INFO [alembic.env] No changes in schema detected
, so no migration. However the db has been created.
Note: crossposting from my issue on FAB's repo
Upvotes: 1
Views: 1136
Reputation: 7945
The key is to drop all the tables (the FAB generated tables and alembic_version
) before you run flask db upgrade
for the first time.
Here is a detailed explanation.
From your projects views.py
, find the line
db.create_all()
and comment it out.
install flask-migrate
go to __init__.py
add in the imports
from flask_migrate import Migrate
add after db = SQLA(app)
migrate = Migrate(app, db)
The setup is done.
Now only one time in the project to initialise the migrations:
flask db init
This will initialise the migrations.
Now do
flask db migrate
This will create the alembic_version
table.
If you do flask db upgrade
now, it will lock up. For one time and one time only, drop all the tables in the database. You may want to back up the data so you can restore it later.
flask db upgrade
This will create all the tables, the FAB tables and the models. Now you may want to restore the data.
From here on you can do the migration workflow in the usual manner. Every time you change things in the models.py
, do:
flask db migrate
flask db upgrade
Don't drop the tables now.
Upvotes: 0
Reputation: 430
This solved the problem for me.
$ flask db stamp head # Set current revision in the database to be head
$ flask db migrate
$ flask db upgrade
Upvotes: 0