Flask从入门到精通之使用Flask-Migrate实现数据库迁移
在开发程序的过程中,你会发现有时需要修改数据库模型,而且修改之后还需要更新数据库。仅当数据库表不存在时,Flask-SQLAlchemy 才会根据模型进行创建。因此,更新表的唯一方式就是先删除旧表,不过这样做会丢失数据库中的所有数据。更新表的更好方法是使用数据库迁移框架。源码版本控制工具可以跟踪源码文件的变化,类似地,数据库迁移框架能跟踪数据库模式的变化,然后增量式的把变化应用到数据库中。
SQLAlchemy 的主力开发人员编写了一个迁移框架,称为Alembic(https://alembic.readthedocs.org/en/latest/index.html)。除了直接使用Alembic 之外,Flask 程序还可使用Flask-Migrate(http://flask-migrate.readthedocs.org/en/latest/)扩展。这个扩展对Alembic 做了轻量级包装,并集成到Flask-Script 中,所有操作都通过Flask-Script 命令完成。
一.创建迁移仓库
首先,我们要在虚拟环境中安装Flask-Migrate:
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 对象上。在这个例子中,MigrateCommand 类使用db 命令附加。
在维护数据库迁移之前,要使用init 子命令创建迁移仓库:
python hello.py db init
Creating directory /home/flask/flask1/migrations ... done
Creating directory /home/flask/flask1/migrations/versions ... done
Generating /home/flask/flask1/migrations/env.pyc ... done
Generating /home/flask/flask1/migrations/alembic.ini ... done
Generating /home/flask/flask1/migrations/README ... done
Generating /home/flask/flask1/migrations/script.py.mako ... done
Generating /home/flask/flask1/migrations/env.py ... done
Please edit configuration/connection/logging settings in
'/home/flask/flask1/migrations/alembic.ini' before proceeding.
这个命令会创建migrations 文件夹,所有迁移脚本都存放其中。数据库迁移仓库中的文件要和程序的其他文件一起纳入版本控制。
二.创建迁移脚本
在Alembic 中,数据库迁移用迁移脚本表示。脚本中有两个函数,分别是upgrade() 和downgrade()。upgrade() 函数把迁移中的改动应用到数据库中,downgrade() 函数则将改动删除。Alembic 具有添加和删除改动的能力,因此数据库可重设到修改历史的任意一点。
我们可以使用revision 命令手动创建Alembic 迁移,也可使用migrate 命令自动创建。手动创建的迁移只是一个骨架,upgrade() 和downgrade() 函数都是空的,开发者要使用Alembic 提供的Operations 对象指令实现具体操作。自动创建的迁移会根据模型定义和数据库当前状态之间的差异生成upgrade() 和downgrade() 函数的内容。自动创建的迁移不一定总是正确的,有可能会漏掉一些细节。自动生成迁移脚本后一定要进行检查。
migrate 子命令用来自动创建迁移脚本:
python hello.py db migrate -m "initial migration"
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected removed table u'sys_user'
INFO [alembic.autogenerate.compare] Detected removed table u'sys_role_privilege'
INFO [alembic.autogenerate.compare] Detected removed table u'sys_role'
INFO [alembic.autogenerate.compare] Detected removed table u'sys_privilege'
INFO [alembic.autogenerate.compare] Detected removed table u'sys_dict'
INFO [alembic.autogenerate.compare] Detected removed table u'user info'
INFO [alembic.autogenerate.compare] Detected removed table u'country'
INFO [alembic.autogenerate.compare] Detected removed table u'sys_user_role'
Generating
/home/flask/flask1/migrations/versions/f52784fdd592_initial_migration.py ... done
三.更新数据库
检查并修正好迁移脚本之后,我们可以使用db upgrade 命令把迁移应用到数据库中:
python hello.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 -> f52784fdd592, initial migration
对第一个迁移来说, 其作用和调用db.create_all() 方法一样。但在后续的迁移中,upgrade 命令能把改动应用到数据库中,且不影响其中保存的数据。
Flask从入门到精通之使用Flask-Migrate实现数据库迁移的更多相关文章
- Flask从入门到精通之大型程序的结构一
尽管在单一脚本中编写小型Web 程序很方便,但这种方法并不能广泛使用.程序变复杂后,使用单个大型源码文件会导致很多问题.不同于大多数其他的Web 框架,Flask 并不强制要求大型项目使用特定的组织方 ...
- Flask从入门到精通之使用Flask-SQLAlchemy管理数据库
Flask-SQLAlchemy 是一个Flask 扩展,简化了在Flask 程序中使用SQLAlchemy 的操作.SQLAlchemy 是一个很强大的关系型数据库框架,支持多种数据库后台.SQLA ...
- Flask从入门到精通之Jinja2模板引擎
我们使用一个简单的例子切入到Jinja2模板引擎,形式最简单的Jinja2模板引擎就是一个包含响应文本的文件,实例如下: <h1>Hello World!</h1> 最简单的包 ...
- Flask从入门到精通之flask扩展
Flask被设计成可扩展形式,因此并没有提供一些重要的功能,比如数据库和用户认证,所以开发者可以自由选择最适合程序的包,或者按需求自行开发.社区成员开发了大量不同用途的扩展,如果这还不能满足需求,你还 ...
- Flask从入门到精通之大型程序的结构二
一.程序包 程序包用来保存程序的所有代码.模板和静态文件.我们可以把这个包直接称为app(应用),如果有需求,也可使用一个程序专用名字.templates 和static 文件夹是程序包的一部分,因此 ...
- Flask从入门到精通之Flash消息
请求完成后,有时需要让用户知道状态发生了变化.这里可以使用确认消息.警告或者错误提醒.一个典型例子是,用户提交了有一项错误的登录表单后,服务器发回的响应重新渲染了登录表单,并在表单上面显示一个消息,提 ...
- Flask从入门到精通之在视图函数中处理表单
在新版hello.py 中,视图函数index() 不仅要渲染表单,还要接收表单中的数据.更新后的index() 视图函数如下: @app.route('/') def index(): name = ...
- Flask从入门到精通之重定向和用户会话
最新版的hello.py 存在一个可用性问题.用户输入名字后提交表单,然后点击浏览器的刷新按钮,会看到一个莫名其妙的警告,要求在再次提交表单之前进行确认.之所以出现这种情况,是因为刷新页面时浏览器会重 ...
- Flask从入门到精通之跨站请求伪造保护
默认情况下,Flask-WTF 能保护所有表单免受跨站请求伪造(Cross-Site Request Forgery,CSRF)的攻击.恶意网站把请求发送到被攻击者已登录的其他网站时就会引发CSRF ...
随机推荐
- MapReduceV1作业生命周期图解以及与YARN基本对比
仿照<hadoop技术内幕:深入解析MapReduce架构设计与实现原理>中的原图,我用手绘制了一份类似的图-_- 4大部分:HDFS,Client,JobTracker,TaskTrac ...
- Eclipse下配置TinyOS开发环境
通过给Eclipse安装Yeti 2 - TinyOS 2 Plugin for Eclipse来配置TinyOS IDE,从而可建立TinyOS Project Yeti 2的介绍请参考网站:htt ...
- HDOJ1242 Rescue(营救) 搜索
Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- 开发中常遇到的Python陷阱和注意点-乾颐堂
最近使用Python的过程中遇到了一些坑,例如用datetime.datetime.now()这个可变对象作为函数的默认参数,模块循环依赖等等. 在此记录一下,方便以后查询和补充. 避免可变对象作为默 ...
- UI设计小白怎样学才能快速入门?
最近有很多同学问我,UI小白有什么捷径可以快速入门?其实我想说设计这门学科没有什么捷径,真的只有多学.多看.多练.多想.多做. 1.先学软件 如果你是小白,软件也不会用,那就先学软件,从PS开始,先看 ...
- 07 Maven 使用Nexus创建私服
7. Maven 使用Nexus创建私服 私服不是 Maven 的核心概念,它仅仅是一种衍生出来的特殊的 Maven 仓库.通过建立自己的私服,就可以降低中央仓库负荷.节省外网带宽.加速 Maven ...
- 关闭文件描述符-close
头文件:#include<unistd.h> 原型:int close(int fd); 返回值:成功返回0,失败返回-1.
- HTTP 500.21 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
问题:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler” IIS7下部署网站出现错误,原因是先安装的II ...
- 2018.08.14 bzoj4241: 历史研究(回滚莫队)
传送们 简单的回滚莫队,调了半天发现排序的时候把m达成了n... 代码: #include<bits/stdc++.h> #define N 100005 #define ll long ...
- HDU 2095 find your present (2) (异或)
题意:给定n个数,让你找出那一个次数为1的. 析:由于题意说了,只有那一个数是奇数,所以其他的都是偶数,根据异或的性质,两个相同的数异或为0: 任何数和0异或得原数,可以很简单的做出这个题. 代码如下 ...