主页
文章
分类
标签
关于
Fastapi的alembic数据库迁移
发布于: 2025-7-7   更新于: 2025-7-7   收录于: Fastapi
文章字数: 920   阅读时间: 2 分钟   阅读量:

Alembic 异步数据库迁移

适用于 FastAPI + SQLAlchemy 异步 ORM 项目,基于 Alembic 1.8+。

安装

1
pip install alembic

初始化迁移仓库

1
alembic init alembic --template async
  • 会在项目根目录生成 alembic/ 文件夹和 alembic.ini
  • --template async 表示使用异步数据库驱动(如 aiomysqlasyncmy
  • 同步项目不需要加该参数

配置 alembic.ini

打开 alembic.ini,注释掉默认的数据库连接字符串:

1
# sqlalchemy.url = driver://user:pass@localhost/dbname

因为数据库 URL 将通过代码动态设置。

配置 env.py

关键修改如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import asyncio
from logging.config import fileConfig

from sqlalchemy import pool
from sqlalchemy.engine import Connection
from sqlalchemy.ext.asyncio import async_engine_from_config
from alembic import context

from settings import settings
from db.base import Base

# 必须导入所有模型,确保 Base.metadata 包含所有表
from db.models import *

config = context.config

# 动态设置数据库 URL
db_url = settings.MYSQL_URL
if not db_url:
    raise ValueError("DB_URL is not set in settings")
config.set_main_option("sqlalchemy.url", db_url)

if config.config_file_name is not None:
    fileConfig(config.config_file_name)

target_metadata = Base.metadata

必须导入所有模型(如 from db.models import *),否则 autogenerate 会认为数据库中没有表,可能生成错误的 DROP TABLE 语句。

基本迁移命令

生成迁移脚本(自动检测模型变更):

1
alembic revision --autogenerate -m "描述变更"

应用迁移(更新数据库):

1
alembic upgrade head

其他常用命令

查看当前版本:

1
alembic current

查看迁移历史:

1
alembic history

回滚上一次迁移:

1
alembic downgrade -1

关键问题与解决方案

新字段无默认值,已有数据行为空

现象
模型中使用 default="test",但数据库中新增列仍为 NULL

原因
default 是 Python 层默认值,仅在通过 SQLAlchemy ORM 创建对象时生效。
它不会生成 SQL 的 DEFAULT 约束,也不影响数据库中已有数据。

正确做法
使用 server_default 设置数据库级默认值:

1
text: Mapped[str] = mapped_column(String(255), server_default="test")

迁移执行时,已有行会自动填充该值。

注意:defaultserver_default 作用层面不同,不可互换。

回滚后无法生成新迁移(Target database is not up to date)

现象
执行 alembic downgrade -1 后,运行 alembic revision --autogenerate 报错。

原因
Alembic 要求生成新迁移时,数据库版本必须与本地最新迁移(head)一致。
回滚后,数据库版本落后于 alembic/versions/ 中的 head,触发保护机制。

解决方法

  1. 删除错误的迁移文件(如 ec704f265356_xxx.py
  2. 确保 alembic headsalembic current 输出一致
  3. 重新生成迁移脚本

在本地开发阶段,删除未部署的迁移文件是安全的做法。

误删迁移文件导致 “Can’t locate revision”

现象

1
Can't locate revision identified by 'xxxx'

原因
数据库 alembic_version 表中记录了一个版本 ID,但本地 alembic/versions/ 目录中已无对应文件。

解决方法(仅限本地开发)

  1. 删除数据库中的版本表:
    1
    
    DROP TABLE alembic_version;
    
  2. 清空或保留基础迁移文件于 alembic/versions/
  3. 重新生成初始迁移:
    1
    2
    
    alembic revision --autogenerate -m "initial"
    alembic upgrade head