flask-migrate是flask的一个扩展模块,主要是扩展数据库表结构的.类似于Django的python manage.py migrate
官方文档: http://flask-migrate.readthedocs.io/en/latest/
安装
pip install flask-migrate
使用举例
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommandapp = Flask(__name__) # 实例化app
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'db = SQLAlchemy(app) # 实例化db
migrate = Migrate(app, db) # 实例化migrate,在db对象创建后调用manager = Manager(app) # 实例化manager
manager.add_command('db', MigrateCommand)class User(db.Model):id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(128))if __name__ == '__main__':manager.run()
执行命令
1、初始化数据库,会创建一个migations文件夹,并且会在数据库中生成一个alembic_version表
python manage.py db init
2、创建迁移历史,在migrations下生成一个version文件夹,下面包含了对应版本的数据库操作py脚本。由于migrate并不一定全部发现你对model的所有改动,因此生成的py脚本需要review, 有错的话则需要edit。例如目前知道的,表名称表更,列名称变更,或给constraints命名等,migreate都不能发现的。更多限制细节见此:Alembic autogenerate documentation
python manage.py db migrate
这条命令可以简单理解为在flask里对数据库(db)进行迁移(migrate)。-m选项用来添加迁移备注信息。从上面的输出信息我们可以看到,Alembic检测出了模型变化:添加了一个新表,删除了一个旧表,并且相应生成了一个迁移脚本。脚本详细信息如下:
"""empty messageRevision ID: d72a7bc93d93
Revises: 7616d2060203
Create Date: 2020-06-30 11:58:46.859000"""# revision identifiers, used by Alembic.
revision = 'd72a7bc93d93'
down_revision = '7616d2060203'from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysqldef upgrade():# ### commands auto generated by Alembic - please adjust! ###op.create_table('MegviiAssset',sa.Column('id', sa.INTEGER(), nullable=False),sa.Column('uuid', sa.String(length=50), nullable=True),)op.drop_table('megviiassset')# ### end Alembic commands ###def downgrade():# ### commands auto generated by Alembic - please adjust! ###op.create_table('megviiassset',sa.Column('id', mysql.INTEGER(display_width=11), autoincrement=True, nullable=False),sa.Column('uuid', mysql.VARCHAR(length=50), nullable=True),sa.PrimaryKeyConstraint('id'),mysql_default_charset=u'utf8',mysql_engine=u'InnoDB')op.drop_table('MegviiAssset')# ### end Alembic commands ###
从上面的代码可以看出,迁移脚本主要包含了两个函数:upgrate()函数用来将改动应用到数据库,而downgrade()函数用来撤消改动
就像这两个函数中的注释所说的,迁移命令是有Alembic自动生成的,其中可能包含错误,所以有必要在生成后检查一下。因为每一次迁移都会生成新的迁移脚本,而且Alemic为每一次迁移都生成了修订版本(revision)ID,所以数据库可以恢复到修改历史中的任一点。正因如此,迁移环境中的文件也要纳入版本控制。
有些复杂的错误无法实现自动迁移,这时可以使用revision命令手动创建迁移脚本。这同样会生成一个迁移脚本,不过脚本中的upgrade()和downgrade()函数都是空的。你需要使用Alembic提供的Operations对象指令在这两个函数中实现具体操作,具体可以访问Alembic官方文档查看。
3、最后一步。此命令相当于执行了version文件夹下的相应py版本,对数据库进行变更操作。此后,对model有变更,只要重复migrate和upgrade操作即可。
python manage.py db upgrade # 更新数据库
如果你想回滚迁移,那么可以使用downgrade命令(降级),它会撤销最后一次迁移在数据库中的改动,这在开发时非常有用。比如,当执行upgrade命令后发现某些地方出错了,这时就可以执行 python manage.py db downgrade 命令进行回滚,删除对应的迁移脚本,重新生成迁移脚本后再进行更新(upgrade)。
坑
1.设计表时字段的默认值,这里用参数server_default,而不是default
operator = db.Column(db.String(40), nullable=True, server_default="init_data")
2.如果报这个错误,将alembic_version表中的数据删掉即可
Heroku Postgres, db migrate fail: alembic.util.exc.CommandError: Can't locate revision identified by
没有migrations文件夹时
- 将 alembic_version 表删除
- 重新初始化 python manage.py db init
- 创建迁移历史并核对相应py文件 python manage.py db migrate
- 更新数据库 python manage.py db upgrade 如果还没有创建数据库和表,这个命令会自动创建,如果已经创建,则会在不损坏数据的前提下执行更新。