Alembic
数据库的管理是一个项目中非常关键的部分。
整个开发过程中免不了要对数据库的结构进行一定的修改,比如字段的增加,字段类型的改变, 或者新添和删除一个表。
比如新建一个表格,朴素的思想(原始的冲动)是代码里补充一个 class,定义好各个字段(可能有50个甚至更多的字段),再一次 create_all()(这也意味着之前的数据会消失),或者在代码部分写好之后,通过数据库软件人肉修改数据库中的结构(想想,几十个字段,甚至上百个字段)。
上述的做法,费时费力,不要忘了,生产工具的使用促进人类社会发展,重复的机械劳动就是浪费生命,聪明的程序员是要学会偷懒的。
所以,今天我们来学习一下 alembic!这是 sqlalchemy 作者亲自开发的 数据库版本管理工具,亲儿子。(需要强调的是,仅仅针对结构化的数据,Mysql PostgreSQL 等)
数据库迁移的终极目的:数据不丢失。
第一步:
pip install alembic # 请确保是你代码运行 python 版本中的 pip
显然,这是为了确保安装了 alembic。之后你就可以在命令行使用 alembic 命令了
第二步:
alembic init alembic_dir # alembic_dir 是自定义的名字,不用加引号
在你的项目的根目录下运行这个指令,不出意外,会出现:(当然,你也可以在别的目录里面这么做,不过,仅仅是使用的话,知道这是个套路就好了,因为 alembic 命令会找当前命令录里的 env.py 文件)
yourproject/
alembic.ini # 相关的初始化配置,主要为 env.py 中的 context 提供相应的参数,我们需要修改的是 sqlalchemy.url 这个
alembic_dir/
env.py # 环境文件,灵活性相当之大
README
script.py.mako # 这是用来生成迁移脚本 py 文件的 mako 语法脚本文件
versions/ # 这个文件里保存着每次 revision 的相关信息
第三步:
编辑 alembic.ini 文件,绑定数据库
sqlalchemy.url = driver://user:pass@localhost/dbname # 把 = 后面的修改成你数据库的配置就可以了,不要加引号
第四步:
在 env.py 中强势插入如下代码,防止在使用 自动迁移命令 时,找不到数据库的路径,参考:stackoverflow
import os
import sys
sys.path.insert(0. os.path.realpath(‘.’))
为了使用模型类实现 自动迁移,还需要设置元数据,这样 alembic 才能获取模型类中定义的信息
1 | from models import Base |
第五步:
比如你的代码里已经创建了一个表模型类,有如下两个操作。
alembic revision -m ‘input your description for this version’ # 这个属于你手动在 versions/fdfadsf.py 去更改,不需要模型类
alembic revision –autogenerate -m ‘input your description for this version’ # 这是自动的,建议用这个,省事,不过在 upgrade 之前一定要自己再 adjust 一下
这两个命令都会在 versions 文件夹里生成一个脚本文件,前者需要手动添加,后者自动生成。
迁移命令生成后之后不要忘记使用命令 alembic upgrade head 使数据库保持最新的状态。
顾名思义, 生成一个版本
此时在该数据库中会生成一个 alembic_version 的表,记录版本信息
注意,其中一旦某个版本缺失,那基本上就可以重来了,alembic 的操作将无法定位版本信息,不过!也可以自己 hack 一下,比如数据库的版本号不在versions里头,我们可以自己生成一个,把版本号给改了,这个大家有兴趣可以自己去玩,灵活性很大,总而言之,还是不希望版本的缺失。
最后介绍几个命令的意思:
alembic current # 显示当前数据库的版本
alembic upgrade head/base/dfas(version num) # head 指更新到最新版本,base 则是最初版本,也可以指定,类似于 git
alembic downgrade base/dfsa(version num) # 降级,如果是 -1 的话,就是直接回退一级 +/- num 代表前进和后退多少个版本
alembic head # 当前最新的版本号是哪个
alembic merge -m ‘fsdf’ asdf fdasf # 合并两个 head
alembic -c test_alembic/alembic.ini dsfajf # 指定目录
具体演示一些可参考的步骤:
pip install alembic,可以用 /anaconda/bin/pip install alembic
alembic init alembic_dir
alembic revision —autogenerate # 自动脚本,初始化数据库,强调 使用 autogenerate 是无法在与最新版本号不一致的情况下使用的
alembic revision -m ‘fasdfads’ # 手动脚本
init data 插入数据,接下来的操作就是在存在数据的情况下进行操作,默认使用 autogenerate
增加字段,删除字段
重命名字段,自动脚本,手动脚本,引申到重命名表格
使用 compare_type=True,然后自动脚本 检测字段类型、长度改变,参考该链接
强调一下,autogenerate 的局限性,参考链接内容
统一再介绍一下几个相关的操作命令
团队使用方面,安利 flask-script 的功能,env.py 给予了充分自定义的可能,可以参考o2o_system的修改模式,可是要强调的是数据库操作是个敏感内容,不管是多大的团队,操作数据库的人总不会有太多,还有就是如何使用 flask-script 简化 命令 的输入。
op.rename_table(
‘old_name’,
‘new_name’
)
op.alter_column(
‘table_name’,
‘old_name’,
‘existing_type’,
‘new_name’
)
一些进阶的说明:
branches 的操作,涉及到了 merge heads 等命令,然后还可以指定 base。
offline mode
自定义配置文件,自定义 configuration
手动定义脚本中还有更多的内容可以学习,operation 有许多方法,比较有用的是批量处理的部分
multidb 模板