Aerich 迁移工具的使用

Aerich 是 Tortoise-ORM 官方配套的数据库迁移工具,核心作用是管理数据库表结构的变更,包括表的创建、字段新增/修改/删除、索引调整等。无需手动编写 DDL 语句,Aerich 可自动识别 Tortoise 模型的变更,生成迁移文件,实现迁移的应用、回滚和历史查询,适配生产环境的表结构管理需求。

一、Aerich 核心作用

在使用 Tortoise-ORM 开发项目时,模型(对应数据库表)会频繁变更(如新增字段、修改字段类型、调整约束),Aerich 主要解决以下问题:

  • 自动识别模型与数据库表的差异,生成标准化迁移文件;
  • 安全应用迁移,将模型变更同步到数据库,不丢失现有数据;
  • 支持迁移回滚,若迁移出错可快速回退到指定版本;
  • 记录迁移历史,便于团队协作和版本管理。

二、Aerich 初始化(前置步骤)

使用 Aerich 前,需先完成初始化操作,生成 Aerich 配置文件和迁移文件目录。前提是:已安装 Aerich(版本 0.9.0 适配 Tortoise-ORM 0.25.0),且项目中已配置好 Tortoise-ORM 连接(如 TORTOISE_ORM 配置字典)。

2.1 初始化命令(项目根目录执行)

在项目根目录(即 main.py 所在目录),运行以下命令,关联 Tortoise-ORM 配置:

# 初始化 Aerich,-t 指定 Tortoise-ORM 配置的路径(格式:模块名.配置字典名)
aerich init -t main.TORTOISE_ORM

注意:命令中 main.TORTOISE_ORM 表示「main.py 文件中的 TORTOISE_ORM 配置字典」。若你的配置不在 main.py 中(如 app/core/config.py 中的 TORTOISE_ORM),需修改为对应路径,例如 aerich init -t app.core.config.TORTOISE_ORM

2.2 初始化生成文件说明

执行上述命令后,项目根目录会自动生成两个核心文件/目录:

  1. pyproject.toml:Aerich 的核心配置文件,记录了迁移相关的配置(如 Tortoise 配置路径、迁移目录、数据库连接等),无需手动修改。
  2. migrations/:迁移文件存储目录,后续生成的所有迁移文件(.sql 或 .py 格式)都会存放在此目录,每个迁移文件对应一次表结构变更。

2.3 初始化数据库(首次必执行)

初始化 Aerich 后,需运行以下命令,初始化数据库迁移环境(生成迁移历史表,用于记录迁移记录):

aerich init-db

执行效果:会在数据库中生成 aerich 表(用于记录迁移历史),同时生成首次迁移文件(对应初始模型的表结构创建),存放在 migrations 目录下。

三、Aerich 核心操作(生成/应用/回滚迁移)

后续开发中,每当 Tortoise 模型发生变更(如新增模型、修改字段、删除字段),都需通过以下步骤,将变更同步到数据库,核心流程:修改模型 → 生成迁移文件 → 应用迁移

3.1 生成迁移文件(模型变更后必执行)

当模型(如 User、Goods 等)发生任何变更后,运行以下命令,Aerich 会自动对比「当前模型」与「数据库表结构」的差异,生成对应的迁移文件:

# 生成迁移文件,--name 指定迁移说明(自定义,便于识别迁移用途)
aerich migrate --name "info"

说明:

  • --name "info":info 可替换为任意描述性字符串(如 "add_user_email_field"、"modify_goods_price_type"),用于说明本次迁移的用途,便于后续查看迁移历史。
  • 生成的迁移文件会存放在 migrations 目录下,文件名包含时间戳和迁移名称,可打开查看自动生成的 SQL 语句(无需手动修改,除非有特殊需求)。

3.2 应用迁移(同步到数据库)

生成迁移文件后,运行以下命令,将迁移文件中的变更(如创建表、修改字段)应用到数据库,完成表结构同步:

aerich upgrade

执行效果:数据库表结构会同步为当前模型的结构,同时 aerich 迁移历史表会新增一条记录,标记本次迁移已应用。

提示:应用迁移前,建议先备份数据库(尤其是生产环境),避免迁移出错导致数据丢失。

3.3 查看迁移历史

运行以下命令,可查看所有迁移记录(包括迁移版本、迁移名称、迁移时间、是否已应用),便于追溯和回滚:

aerich history

输出示例:会按时间顺序列出所有迁移文件,标记每个迁移的状态(已应用/未应用),清晰查看表结构变更记录。

3.4 回滚迁移(迁移出错时使用)

若应用迁移后发现问题(如字段类型错误、约束设置不当),可运行以下命令,回滚到上一个迁移版本:

# 回滚到上一个迁移版本
aerich downgrade

补充说明:

  • 默认回滚到上一个版本,若需回滚到指定版本,可在命令后添加 --to 版本号(版本号可通过 aerich history 查看)。
  • 回滚后,数据库表结构会恢复到对应迁移版本的状态,迁移历史表也会同步更新。
  • 生产环境回滚需谨慎,回滚前需确认无数据丢失风险(如回滚删除字段的迁移,会丢失该字段的所有数据)。

四、Tortoise 模型案例(适配 Aerich 迁移)

以下是一个标准的 Tortoise 模型案例(可直接用于测试 Aerich 迁移),模型定义后,可通过上述 Aerich 命令,生成迁移文件并应用到数据库:

from tortoise.models import Model
from tortoise.fields import CharField, DatetimeField, BooleanField

# 定义 User 模型(对应数据库中的 users 表)
class User(Model):
    # 主键:UUID 字符串(max_length=36 适配 UUID 长度),pk=True 表示为主键
    id = CharField(max_length=36, pk=True)
    # 用户名:字符串,max_length=50,unique=True 表示唯一约束(不可重复)
    username = CharField(max_length=50, unique=True)
    # 邮箱:字符串,max_length=255,唯一约束
    email = CharField(max_length=255, unique=True)
    # 是否激活:布尔值,default=True 表示默认激活
    is_active = BooleanField(default=True)
    # 创建时间:datetime 类型,auto_now_add=True 表示创建时自动填充当前时间
    created_at = DatetimeField(auto_now_add=True)
    # 更新时间:datetime 类型,auto_now=True 表示修改时自动更新为当前时间
    updated_at = DatetimeField(auto_now=True)

    # Meta 类:用于配置模型的额外属性(与数据库表相关)
    class Meta:
        table = "users"  # 自定义数据库表名(默认会将模型名转为小写复数,此处手动指定为 users)
        ordering = ["-created_at"]  # 默认查询排序:按创建时间降序(最新创建的用户排在前面)

    # 自定义字符串表示:打印 User 对象时,显示用户名(便于调试)
    def __str__(self):
        return self.username

模型迁移测试步骤(实操)

  1. 复制上述模型代码,保存到项目的 models.py 文件中;
  2. 运行 aerich migrate --name "create_user_model",生成创建 users 表的迁移文件;
  3. 运行 aerich upgrade,将 users 表应用到数据库;
  4. 运行 aerich history,查看本次迁移记录;
  5. 若需测试修改模型:新增一个 phone = CharField(max_length=11, null=True) 字段,重复步骤 2-3,观察数据库表结构变化。

五、常见问题与避坑指南

  • 问题1:初始化时提示「No module named 'main'」:原因是 aerich init -t main.TORTOISE_ORM 中,main 模块路径错误。检查 main.py 是否存在,或修改为实际的配置路径(如 app.core.config.TORTOISE_ORM)。
  • 问题2:生成迁移文件时,未识别到模型变更:确保模型所在的模块,已添加到 Tortoise-ORM 配置的 apps.models 列表中(如 "app.models"),否则 Aerich 无法扫描到模型。
  • 问题3:应用迁移时提示「Table already exists」:原因是数据库中已存在对应表(如手动创建的 users 表),需删除该表后,重新执行 aerich upgrade
  • 问题4:回滚迁移失败:检查是否有后续迁移已应用,需先回滚后续迁移,再回滚当前迁移;或确认迁移文件未被手动修改,手动修改迁移文件可能导致回滚失败。
posted @ 2026-02-04 15:35  向闲而过  阅读(0)  评论(0)    收藏  举报