Python的Flask框架中使用Flask-Migrate扩展迁移数据库的教程


Posted in Python onJune 14, 2016

我们在升级系统的时候,经常碰到需要更新服务器端数据结构等操作,之前的方式是通过手工编写alter sql脚本处理,经常会发现遗漏,导致程序发布到服务器上后无法正常使用。

现在我们可以使用Flask-Migrate插件来解决之,Flask-Migrate插件是基于Alembic,Alembic是由大名鼎鼎的SQLAlchemy作者开发数据迁移工具。

具体操作如下:

1. 安装Flask-Migrate插件

$ pip install Flask-Migrate
2. 修改Flask App部分的代码,以增加Migrate相关的Command
db = SQLAlchemy(app)
migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

3. 初始化

$ python app.py db init

使用Flask-Migrate迁移数据库
随着开发进度不断向前,你会发现你的数据库模型需要更改,而当这种情况发生时需要更新数据库。

Flask-SQLAlchemy只有当数据库表不存在了才从模型创建它们,所以更新表的唯一途径就是销毁旧的表,当然这将导致所有数据库中的数据丢失。

有个更好的解决方案就是使用数据库迁移框架。和源码版本控制工具跟踪更改源码文件一样,数据库迁移框架跟踪更改数据库模型,然后将增量变化应用到数据库中。

SQLAlchemy的主要开发人员写了一个Alembic迁移框架,但我们不直接使用Alembic,Flask应用可以使用Flask-Migrate扩展,一个集成了Flask-Script来提供所有操作命令的轻量级Alembic包。

4. 创建迁移仓库

首先,Flask-Migrate必须已经安装到虚拟环境中:

(venv) $ pip install flask-migrate

下面展示扩展如何初始化:

from flask.ext.migrate import Migrate, MigrateCommand 

# ...

migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)

为了可以使用数据库迁移命令,Flask-Migrate提供MigrateCommand类来连接Flask-Script的manager对象。在这个示例中使用db来连接到命令。

在数据库迁移可以维护之前,必须通过init子命令来创建一个迁移库:

(venv) $ python hello.py db init
Creating directory /home/flask/flasky/migrations...done
 Creating directory /home/flask/flasky/migrations/versions...done
 Generating /home/flask/flasky/migrations/alembic.ini...done
 Generating /home/flask/flasky/migrations/env.py...done
 Generating /home/flask/flasky/migrations/env.pyc...done
 Generating /home/flask/flasky/migrations/README...done
 Generating /home/flask/flasky/migrations/script.py.mako...done
 Please edit configuration/connection/logging settings in
 '/home/flask/flasky/migrations/alembic.ini' before proceeding.

这个命令创建一个migrations文件夹,里面存放了所有迁移脚本。

建议:如果你有克隆在GitHub上的应用程序,你现在可以运行git checkout 5c来切换到这个版本的应用程序。

5. 创建迁移脚本

在Alembic,数据库迁移工作由迁移脚本完成。这个脚本有两个函数,分别叫做upgrade()和downgrade()。upgrade()函数实施数据库更改,是迁移的一部分,downgrade()函数则删除它们。通过添加和删除数据库变化的能力,Alembic可以重新配置数据库从历史记录中的任何时间点。

Alembic迁移可以分别使用revision和migrate命令手动或自动创建。手动迁移通过由开发人员使用Alembic的Operations对象指令实现的空upgrade()和downgrade()函数创建迁移框架脚本。另一方面,自动迁移通过寻找模型定义和数据库当前状态间的不同为upgrade()和downgrade()生成代码。

警告:自动迁移并不总是准确的,可以忽略一些细节。所以应该经常审查一下自动生成的迁移脚本。
migrate子命令创建自动迁移脚本:

(venv) $ python hello.py db migrate -m "initial migration"
INFO [alembic.migration] Context impl SQLiteImpl.
INFO [alembic.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate] Detected added table 'roles'
INFO [alembic.autogenerate] Detected added table 'users'
INFO [alembic.autogenerate.compare] Detected added index
'ix_users_username' on '['username']'
 Generating /home/flask/flasky/migrations/versions/1bc
 594146bb5_initial_migration.py...done

建议:如果你有克隆在GitHub上的应用程序,你现在可以运行git checkout 5c来切换到这个版本的应用程序。注意,你不需要为这个应用生成migrations,所有的迁移脚本都包含在版本库中。
6. 更新数据库

一旦迁移脚本被审查且接受,就可以使用db upgrade命令更新到数据库中:

(venv) $ python hello.py db upgrade
INFO [alembic.migration] Context impl SQLiteImpl.
INFO [alembic.migration] Will assume non-transactional DDL.
INFO [alembic.migration] Running upgrade None -> 1bc594146bb5, initial migration

第一次迁移实际上相当于调用db.create_all(),但在后续迁移中,upgrade命令对表实施更新操作但不影响表中的内容。

Python 相关文章推荐
Python合并两个字典的常用方法与效率比较
Jun 17 Python
基于python的Tkinter实现一个简易计算器
Dec 31 Python
Python编程修改MP3文件名称的方法
Apr 19 Python
对python .txt文件读取及数据处理方法总结
Apr 23 Python
python基于物品协同过滤算法实现代码
May 31 Python
python使用递归的方式建立二叉树
Jul 03 Python
python脚本实现音频m4a格式转成MP3格式的实例代码
Oct 09 Python
Python函数的返回值、匿名函数lambda、filter函数、map函数、reduce函数用法实例分析
Dec 26 Python
Tensorflow: 从checkpoint文件中读取tensor方式
Feb 10 Python
Python Switch Case三种实现方法代码实例
Jun 18 Python
解决Windows下python和pip命令无法使用的问题
Aug 31 Python
FP-growth算法发现频繁项集——发现频繁项集
Jun 24 Python
Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
Jun 14 #Python
全面了解Python的getattr(),setattr(),delattr(),hasattr()
Jun 14 #Python
浅谈python中的getattr函数 hasattr函数
Jun 14 #Python
深入解析Python中的线程同步方法
Jun 14 #Python
详解Python中的Descriptor描述符类
Jun 14 #Python
浅析Python中的getattr(),setattr(),delattr(),hasattr()
Jun 14 #Python
Python中getattr函数和hasattr函数作用详解
Jun 14 #Python
You might like
收集的PHP中与数组相关的函数
2007/03/22 PHP
php中get_headers函数的作用及用法的详细介绍
2013/04/27 PHP
PHP中使用asort进行中文排序失效的问题处理
2014/08/18 PHP
php获取远程图片并下载保存到本地的方法分析
2016/10/08 PHP
PHP实现的字符串匹配算法示例【sunday算法】
2017/12/19 PHP
在phpstudy集成环境下的nginx服务器下配置url重写
2019/12/02 PHP
创建一个复制UBB软件信息的链接或按钮的js代码
2008/01/06 Javascript
jQuery 判断页面元素是否存在的代码
2009/08/14 Javascript
javascript闭包的高级使用方法实例
2013/07/04 Javascript
js如何实现设计模式中的模板方法
2013/07/23 Javascript
JavaScript限定复选框的选择个数示例代码
2013/08/25 Javascript
JavaScript必知必会(三) String .的方法来自何方
2016/06/08 Javascript
AngularJS中下拉框的高级用法示例
2017/10/11 Javascript
Vue组件化开发思考
2018/02/02 Javascript
基于vue-cli npm run build之后vendor.js文件过大的解决方法
2018/09/27 Javascript
详解webpack+ES6+Sass搭建多页面应用
2018/11/05 Javascript
深入理解js A*寻路算法原理与具体实现过程
2018/12/13 Javascript
layui 上传插件 带预览 非自动上传功能的实例(非常实用)
2019/09/23 Javascript
antd多选下拉框一行展示的实现方式
2020/10/31 Javascript
python读取Android permission文件
2013/11/01 Python
python中的hashlib和base64加密模块使用实例
2014/09/02 Python
python使用os.listdir和os.walk获得文件的路径的方法
2017/12/16 Python
python使用requests模块实现爬取电影天堂最新电影信息
2019/04/03 Python
Python closure闭包解释及其注意点详解
2019/08/28 Python
pytorch 数据处理:定义自己的数据集合实例
2019/12/31 Python
Windows+Anaconda3+PyTorch+PyCharm的安装教程图文详解
2020/04/03 Python
opencv之颜色过滤只留下图片中的红色区域操作
2020/06/05 Python
Python实现PS滤镜中的USM锐化效果
2020/12/04 Python
css3实现圆锥渐变conic-gradient效果
2020/02/12 HTML / CSS
CK巴西官方网站:Calvin Klein巴西
2019/07/19 全球购物
促销活动方案模板
2014/02/24 职场文书
涉密人员保密承诺书
2014/05/28 职场文书
毕业生找工作自荐书
2014/06/30 职场文书
创建绿色学校先进个人材料
2014/08/20 职场文书
学院党的群众路线教育实践活动第一阶段情况汇报
2014/10/25 职场文书
亮剑观后感600字
2015/06/05 职场文书