记录一下使用 sqlalchemy-migrate 的问题。
官网: https://sqlalchemy-migrate.readthedocs.io/en/latest/download.html
说明
在寻找 python 层面,类 rails migration 的工具,发现了 sqlalchemy-migrate。
大致看着还可以,尝试使用中。
下载
1
pip install sqlalchemy-migrate
安装成功后,应该可以运行
可以查看 migrate 脚本支持的功能命令。
使用
根据官网说明,手动尝试运行,但遇到了些问题。
创建迁移项目目录
1
migrate create migration "Example project"
此命令会创建一个迁移项目的文件夹 migration,里面包含有 versions 目录、manage.py、manage.cfg 文件。
构建数据库的基本结构
官网上,有
1
$ python migration/manage.py version_control mysql+mysqldb://root:@localhost/activity?charset=utf8mb4 migration
官网上说,这命令会在相应的数据库中增加版本控制的表 migrate_version。但在我的机器中,会出现错误
1
2
3
4
Traceback (most recent call last):
File "migration/manage.py", line 2, in <module>
from migrate.versioning.shell import main
ModuleNotFoundError: No module named 'migrate'
查阅文件 migration/manage.py 文件,
1
2
3
4
5
#!/usr/bin/env python
from migrate.versioning.shell import main
if __name__ == '__main__':
main(debug='False')
报错没有正常找到 migrate 包,折腾了许久,没有找到有效的解决方案。
但本质上,migration/manage.py 文件也是使用 migrate 命令去实现迁移操作的,
所以,尝试手动使用 migrate 命令去实现数据迁移。
1
migrate version_control mysql+mysqldb://root:@localhost/activity?charset=utf8mb4 migration
运行上面的命令之后,查看数据库,会发现有数据表 migrate_version。
查看当前版本
1
2
migrate db_version mysql+pymysql://root:@localhost/activity?charset=utf8mb4 migration
# 0
创建迁移脚本
创建迁移脚本使用 script
命令实现
1
migrate script "add init tables" migration
命令会生成文件 migration/xxx_add_init_tables.py
文件,xxx
可以是 001 增序编号,也可以是日期时间。
查阅文件,有
1
2
3
4
5
6
7
8
9
10
11
12
13
from sqlalchemy import *
from migrate import *
def upgrade ( migrate_engine ):
# Upgrade operations go here. Don't create your own engine; bind
# migrate_engine to your metadata
pass
def downgrade ( migrate_engine ):
# Operations to reverse the above upgrade go here.
pass
遇到问题:使用timestamp做为文件名前缀时,migrate包的部分版本处理有错误,建议使用普通数字。
增加一个 users 表, 有代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from sqlalchemy import *
from migrate import *
meta = MetaData ()
account = Table (
'account' , meta ,
Column ( 'id' , Integer , primary_key = True ),
Column ( 'login' , String ( 40 )),
Column ( 'passwd' , String ( 40 )),
)
def upgrade ( migrate_engine ):
meta . bind = migrate_engine
account . create ()
def downgrade ( migrate_engine ):
meta . bind = migrate_engine
account . drop ()
例子中,利用 sqlalchemy 构建表,并分别定义了 upgrade 、downgrade 方法。方法中,分别对 account 表进行了创建或删除。
代码中定义了表,需要将表落实到数据库中,运行命令
1
migrate upgrade mysql + pymysql : // root : @localhost / activity ? charset = utf8mb4 migration
命令会直接在数据库创建相应的表。
想删除表,可以执行
1
migrate downgrade mysql + pymysql : // root : @localhost / activity ? charset = utf8mb4 migration 0
0
表示要回滚到的版本。