Flask-Migrate
数据库迁移框架,它也是flask的一个扩展,比较受欢迎。其实也可以直接用Alembic,它是SQLAlchemy主力开发人员编写的迁移框架,不过Flask-Migrate对它做了轻量级包装,并集成在Flask-Script中,所有操作都通过Flask-Script命令完成。让人使用起来更爽。
- 注意 - 数据库迁移仓库中的文件要和其他的文件一起纳入版本控制。
安装
pip install flask-migrate # 直接最简单pip安装就好
Migrate的代码配置以及迁移配置步骤
为了可以使用数据库迁移命令,Flask-Migrate提供MigrateCommand类来连接Flask-Script的manager对象。所以呢,我们可以用命令去操控这些迁移任务。
```python
coding=UTF8
from flask_sqlalchemy import SQLAlchemy from flask import Flask from flask_migrate import Migrate, MigrateCommand from flask_script import Manager
app = Flask(name) app.config['SQLALCHEMYDATABASEURI'] = 'mysql+mysqlconnector://root:123456@localhost:3306/tedcallmozu' app.config['SQLALCHEMYTRACK_MODIFICATIONS'] = True db = SQLAlchemy(app) migration = Migrate(app,db) manager = Manager(app) manager.add_command('db',MigrateCommand) # 这里MigrateCommand类是使用db命令附加的,也就是到时候命令用db if __name == "__main": manager.run() # 运行
- 1.创建迁移仓库
> 注意一般新创建的项目我们一开始是要执行这个命令,不过如果是那种clone的项目,一般这个迁移仓库是放进git版本控制里的,我们不要在去初始化它了,因为已经存在了这个迁移仓库。
这个命令会去创建migration文件夹,这个文件夹是在运行py文件的当前目录下,到时候所有迁移脚本都会存放在这里。
```python
python models.py db init # 使用命令或者在pycharm运行配置里设置script param
'''运行结果'''
'''/Users/pocket/python_virtual/Tracker_venv2.7/bin/python /Users/pocket/Desktop/tracker-master/Mozu/Models/mozuModels.py db init
Creating directory /Users/pocket/Desktop/tracker-master/Mozu/Models/migrations ... done
Creating directory /Users/pocket/Desktop/tracker-master/Mozu/Models/migrations/versions ... done
Generating /Users/pocket/Desktop/tracker-master/Mozu/Models/migrations/alembic.ini ... done
Generating /Users/pocket/Desktop/tracker-master/Mozu/Models/migrations/env.py ... done
Generating /Users/pocket/Desktop/tracker-master/Mozu/Models/migrations/env.pyc ... done
Generating /Users/pocket/Desktop/tracker-master/Mozu/Models/migrations/README ... done
Generating /Users/pocket/Desktop/tracker-master/Mozu/Models/migrations/script.py.mako ... done
Please edit configuration/connection/logging settings in '/Users/pocket/Desktop/tracker-master/Mozu/Models/migrations/alembic.ini' before proceeding.
Process finished with exit code 0
'''
- 2.创建迁移脚本
> 在Alembic,数据库迁移工作由迁移脚本完成。这个脚本有两个函数,分别叫做upgrade()和downgrade()。upgrade()函数实施数据库更改,是迁移的一部分,downgrade()函数则删除它们。通过添加和删除数据库变化的能力,Alembic可以重新配置数据库从历史记录中的任何时间点。
Alembic迁移可以分别使用revision和migrate命令手动或自动创建
> - 迁移脚本因为是放在版本控制里管理,第一个提交的人,下一个人要用就直接拉取迁移脚本进行更新就好了,不要去在提交一次,跟git版本差不多类似
```python
python models.py db migrate -m "迁移脚本提交记录,类似一种版本控制"
# python models.py db revision -m "迁移脚本提交记录,类似一种版本控制" # 手动创建迁移脚本,这里只是一个骨架,里面的upgrade()和downgrade()函数都是空的
```
- 3.更新数据库
> 脚本创建成功没有报错,一般就可以进行数据库更新操作。
> - 注意如果脚本里对一些键值或者表删除,而这些值有关联外键,是删不了的,直接提示报错。
```python
python models.py db upgrade # 更新数据库
'''运行结果'''
'''
/Users/pocket/python_virtual/Tracker_venv2.7/bin/python /Users/pocket/Desktop/tracker-master/Mozu/Models/mozuModels.py db upgrade
INFO [alembic.runtime.migration] Context impl MySQLImpl. INFO [alembic.runtime.migration] Will assume non-transactional DDL. INFO [alembic.runtime.migration] Running upgrade -> c53cae9788e7, init mozu database '''
```
4.手动编写脚本代码
def upgrade(): # ### commands auto generated by Alembic - please adjust! ### # 添加字段,并未字段设置各种属性 op.add_column('tracker_device', sa.Column('accHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('adcHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('baseHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('bleHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('customer', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('customerPro', sa.Integer(), server_default=sa.text(u'1'), nullable=True)) op.add_column('tracker_device', sa.Column('dogHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('headHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('microHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('relayHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('scmHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device', sa.Column('wifiHardwear', sa.Integer(), server_default=sa.text(u'0'), nullable=True)) op.add_column('tracker_device_mqttRecordRecord', sa.Column('packet', sa.PickleType(), nullable=True)) # 修改字段类型等 op.alter_column('tracker_userFences', 'devices', type_=sa.PickleType) op.alter_column('tracker_userFences', 'data', type_=sa.PickleType) op.alter_column('tracker_device_parameterInfo', 'data', type_=sa.PickleType) op.alter_column('tracker_device_selfCheckInfo', 'gsensor', type_=sa.PickleType) op.alter_column('tracker_device_selfCheckInfo', 'gps', type_=sa.PickleType) op.alter_column('tracker_device_stateAndEventRecord', 'data', type_=sa.PickleType) op.alter_column('tracker_device_sendParamRecord', 'data', type_=sa.PickleType) # ### end Alembic commands ### def downgrade(): # ### commands auto generated by Alembic - please adjust! ### op.alter_column('tracker_device_sendParamRecord', 'data', type_=sa.String(512)) op.alter_column('tracker_device_stateAndEventRecord', 'data', type_=sa.String(512)) op.alter_column('tracker_device_selfCheckInfo', 'gsensor', type_=sa.String(512)) op.alter_column('tracker_device_selfCheckInfo', 'gps', type_=sa.String(512)) op.alter_column('tracker_device_parameterInfo', 'data', type_=sa.String(512)) op.alter_column('tracker_userFences', 'data', type_=sa.String(512)) op.alter_column('tracker_userFences', 'devices', type_=sa.String(128)) op.drop_column('tracker_device_mqttRecordRecord', 'packet') op.drop_column('tracker_device', 'wifiHardwear') op.drop_column('tracker_device', 'scmHardwear') op.drop_column('tracker_device', 'relayHardwear') op.drop_column('tracker_device', 'microHardwear') op.drop_column('tracker_device', 'headHardwear') op.drop_column('tracker_device', 'dogHardwear') op.drop_column('tracker_device', 'customerPro') op.drop_column('tracker_device', 'customer') op.drop_column('tracker_device', 'bleHardwear') op.drop_column('tracker_device', 'baseHardwear') op.drop_column('tracker_device', 'adcHardwear') op.drop_column('tracker_device', 'accHardwear') # ### end Alembic commands ###