使用Alembic进行数据迁移

大型 FastAPI 项目 中,数据库迁移(Database Migration)功能通常使用 Alembic 进行管理,并且存放在 migrations/ 目录下。

1. 数据库迁移的目录结构

在 FastAPI 项目中,数据库迁移的目录结构如下:

my_fastapi_project/
│── app/ # 应用主目录
│ ├── core/ # 核心配置
│ │ ├── database.py # 数据库连接
│ │ ├── config.py # 配置管理
│ │ ├── __init__.py
│── migrations/ # Alembic 迁移管理
│ ├── versions/ # 存放迁移版本文件
│ ├── env.py # Alembic 配置文件
│ ├── script.py.mako # 迁移模板
│ ├── README # 迁移说明
│ ├── alembic.ini # Alembic 配置
│── .env # 环境变量
│── requirements.txt # 依赖项
│── alembic.ini # Alembic 配置
│── Dockerfile # Docker 配置
│── docker-compose.yml # Docker-Compose 配置
│── README.md # 项目说明

其中:

​ • migrations/:存放数据库迁移的所有内容。

​ • migrations/versions/:存放具体的迁移版本文件(XXXX_initial_migration.py)。

​ • migrations/env.py:Alembic 运行时的数据库环境配置。

​ • alembic.ini:Alembic 全局配置文件。

2. 配置 Alembic 进行数据库迁移

第一步:安装 Alembic

pip install alembic

第二步:初始化 Alembic

在项目根目录运行:

alembic init migrations

执行后,会在项目目录下生成 migrations/ 目录,结构如下:

migrations/
│── versions/ # 迁移版本文件夹
│── env.py # Alembic 运行时配置
│── script.py.mako # 迁移模板
│── README # 说明文件
│── alembic.ini # Alembic 配置文件

3. 配置 env.py 连接数据库

打开 migrations/env.py,找到 config = context.config,修改如下:

from logging.config import fileConfig
from sqlalchemy import engine_from_config, create_engine
from sqlalchemy import pool
from alembic import context
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
fileConfig(config.config_file_name)
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
from app.models import * # noqa: F401
# target_metadata = mymodel.Base.metadata
from app.models.base import Base # noqa: F401
# target_metadata = None
target_metadata = Base.metadata
# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.
from app.core.config import settings # noqa: F401
config.set_main_option("sqlalchemy.url", settings.MYSQL_DATABASE_URL)
def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online() -> None:
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
# connectable = engine_from_config(
# config.get_section(config.config_ini_section, {}),
# prefix="sqlalchemy.",
# poolclass=pool.NullPool,
# )
engine = create_engine(settings.MYSQL_DATABASE_URL)
with engine.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()

⚠️ 注意

​ • 需要导入 Base.metadata,否则 Alembic 无法识别你的数据模型。

​ • DATABASE_URL 从 app/core/config.py 读取,保证与应用使用的数据库一致。

4. 创建数据库迁移

当你新增或修改模型时,运行以下命令:

alembic revision --autogenerate -m "Initial migration"

这将在 migrations/versions/ 目录中生成类似于:

migrations/versions/
│── 20240101123045_initial_migration.py

示例迁移文件 (20240101123045_initial_migration.py)

from alembic import op
import sqlalchemy as sa
# 迁移 ID(自动生成)
revision = '20240101123045'
down_revision = None # 如果是第一个迁移,设置为 None
branch_labels = None
depends_on = None
def upgrade():
"""数据库升级操作"""
op.create_table(
'users',
sa.Column('id', sa.Integer(), primary_key=True, autoincrement=True),
sa.Column('username', sa.String(length=50), nullable=False, unique=True),
sa.Column('email', sa.String(length=100), nullable=False, unique=True),
sa.Column('hashed_password', sa.String(length=200), nullable=False),
)
def downgrade():
"""数据库降级操作(回滚)"""
op.drop_table('users')

该文件:

​ • upgrade():定义数据库表的新增、修改操作。

​ • downgrade():定义数据库表的回滚操作。

5. 应用数据库迁移

创建迁移文件后,执行以下命令将其应用到数据库:

alembic upgrade head

​ • 成功后,数据库中会创建 users 表。

如果需要回滚数据库(撤销迁移),可以执行:

alembic downgrade -1

或者回滚到指定版本:

alembic downgrade <revision_id>

6. 如何在 Docker 里运行数据库迁移?

如果你使用 Docker 进行部署,在 docker-compose.yml 里,你可以使用 entrypoint.sh 自动执行数据库迁移:

#!/bin/sh
# 等待数据库启动
sleep 5
# 运行 Alembic 迁移
alembic upgrade head
# 启动 FastAPI 应用
exec uvicorn app.main:app --host 0.0.0.0 --port 8000

然后在 Dockerfile 里添加:

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

7. 总结

数据库迁移代码存放在 migrations/ 目录下

env.py 负责连接数据库和 ORM 绑定

使用 alembic revision --autogenerate 生成迁移文件

使用 alembic upgrade head 执行数据库迁移

可以在 Docker 部署时自动执行迁移

这样,你的 FastAPI 项目就可以安全地进行数据库结构变更,保持版本一致性!🚀

posted on   朝朝暮Mu  阅读(68)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
< 2025年3月 >
23 24 25 26 27 28 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 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示