使用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 项目就可以安全地进行数据库结构变更,保持版本一致性!🚀
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人