Alembic数据迁移

Alembic是SQLAlchemy的一款数据迁移工具,它也是由SQLAlchemy作者开发的,这篇笔记我们简单介绍Alembic的用法。

为什么使用数据迁移

前面代码我们曾演示过,SQLAlchemy本身支持根据数据模型定义自动建表。如下写法会在数据表不存在时自动创建,数据表存在时则跳过。

Base.metadata.create_all(engine)

但上面这种自动建表对数据表变更的管理实在太粗糙了,如果我们不是新增一个表而是修改了一个表结构,上面代码就无法处理了。

实际开发中,对于大型企业级项目(尤其是Java领域中使用MyBatis框架时),数据库可能专门由DBA维护,对于数据表的变更可能由程序员手写包含DDL语句的SQL脚本,脚本的版本管理也是手动完成,但这种传统方式不太适用于轻量级、敏捷的开发模式。一旦用到SQLAlchemy、Django(ORM)这类全功能ORM框架,我们的编码方式通常更倾向于Code First,即先编写数据模型再通过数据迁移表更数据库表,主流的开发方式都会搭配数据迁移工具自动生成和管理表更脚本。

安装Alembic

我们使用pip命令安装即可,安装完成后,我们当前的虚拟环境下会获得alembic命令行工具。

pip install alembic

初始化Alembic环境

Alembic其实和Git有点神似,毕竟它们都是一种变更版本管理工具,只不过Alembic维护的是数据迁移。使用Alembic前,我们需要先初始化Alembic环境,在项目根目录执行以下命令。

alembic init alembic

alembic init命令用于初始化,第二个alembic其实是项目名。执行完成后,我们会看到项目根目录出现了一些新的文件和文件夹。

工程根目录
  |_ alembic
    |_ versions   # 存储具体迁移脚本的目录
    |_ env.py     # 迁移内容定义代码
  |_ alembic.ini  # Alembic配置文件,用于指定数据库连接等信息
  |_ app          # 其它工程文件,这里仅作为例子,例如我们的具体业务Python代码
    |_ models.py
    |_ main.py

现在Alembic还不能直接使用,我们还需要修改相关配置和代码。首先我们需要编辑alembic.ini,在其中配置数据库连接,这里我们使用同步模式的pymysql驱动包(如果你使用的是异步驱动包,初始化Alembic时配置有些不同,在本文最后对此进行了介绍)。

sqlalchemy.url = mysql+pymysql://root:root@localhost:3306/netstore

然后配置env.py,我们需要修改target_metadata,将其指向Base.metadata,这样Alembic才能找到我们要迁移的数据模型定义。

target_metadata = app.models.Base.metadata

创建数据迁移

执行以下命令创建数据迁移。

alembic revision --autogenerate -m "添加conf表"
  • --autogenerate:根据模型与当前数据库状态的差异自动生成迁移脚本
  • -m:添加描述性信息,便于管理

执行完成后,生成的数据迁移脚本位于versions文件夹下,其中包含了执行迁移和回退迁移的代码逻辑。

执行数据迁移

执行以下命令将数据库内的表结构等信息拉齐到最新版本,其中head表示最新迁移。

alembic upgrade head

执行完成后,我们会看到数据库中自动创建了alembic_version表,其中记录了当前数据库内已经执行的数据迁移版本信息。

如果我们想回退,可以使用alembic downgrade命令,例如以下命令回滚一步。

alembic downgrade -1

其它数据迁移管理操作

Alembic还提供了一些命令用于查看迁移历史、回退到特定版本等。

查看当前版本

alembic current

查看迁移历史

alembic history

回退到特定版本

alembic downgrade <revision_id>

其中,revision_id是要回退的版本号,它可以通过alembic history命令获取。

使用异步数据库驱动

如果你使用的是异步数据库驱动,例如aiomysql,上面介绍的操作方式需要稍微修改一下。初始化Alembic环境时,我们需要使用异步的项目模板。

alembic init -t async alembic

此时在alembic.ini中,我们就可以配置使用异步驱动的数据库连接了。

sqlalchemy.url = mysql+aiomysql://root:root@localhost:3306/netstore
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。