Migración de base de datos con Alembic
En este capítulo aprenderás a usar Alembic para gestionar cambios en la estructura de la base de datos, y a comprender las similitudes y diferencias con Django Migration y Flask-Migrate.
¿Por qué necesitas una herramienta de migración?
Base.metadata.create_all()También tiene un defecto fatal: solo crea tablas cuando no existen; las modificaciones de la estructura de tablas existentes no se sincronizan automáticamente.
AlembicEs la herramienta oficial de migración de SQLAlchemy; la de Djangomakemigrations/migratey Flask-Migrate de Flask, en su núcleo están inspirados en el diseño de Alembic.
Instalación e inicialización
(venv) $ pip install alembic (venv) $ alembic init alembic Creating directory alembic/... done
Estructura de directorios generada:
alembic/ ├── versions/ # 迁移脚本存放目录 ├── env.py # 迁移环境配置(需手动修改!) └── script.py.mako # 迁移脚本模板 alembic.ini # Alembic 配置文件
Configura env.py para conectarlo a tus modelos
Este es un paso clave: Alembic, por defecto, no sabe dónde están tus modelos SQLAlchemy.
Ejemplo
import sys
from pathlib import Path
# Agrega el directorio raíz del proyecto a sys.path (garantiza que puedas importar tus propios módulos)
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from database import Base, engine
from models import Category, Post # Importa todos los modelos para asegurar que Base.metadata los contenga
# target_metadata debe establecerse en los metadatos del modelo
target_metadata = Base.metadata
Al mismo tiempo, modificaalembic.inila conexión de base de datos en:
# 文件路径:alembic.ini sqlalchemy.url = sqlite:///./blog.db
Los tres pasos de la migración
| Paso | Comando | Función | Equivalente en Django |
|---|---|---|---|
| Inicialización | alembic init alembic | Crear el entorno de migración (solo una vez) | — |
| Generar | alembic revision --autogenerate -m "descripción" | Detecta cambios en los modelos y genera el script de migración | makemigrations |
| Ejecutar | alembic upgrade head | Ejecuta todas las migraciones no aplicadas | migrate |
Generar y ejecutar migraciones
(venv) $ alembic revision --autogenerate -m "初始化 Post 和 Category 模型" INFO [alembic.autogenerate] Detected added table 'categories' INFO [alembic.autogenerate] Detected added table 'posts' Generating alembic/versions/xxxx_initial.py ... done (venv) $ alembic upgrade head INFO [alembic.runtime.migration] Running upgrade -> xxxx, 初始化
Práctica: agregar el campo read_count
Ejemplo
class Post(Base):
# ... campos existentes ...
read_count = Column(Integer, default=0) # Número de lecturas
(venv) $ alembic revision --autogenerate -m "Post 新增 read_count 字段" (venv) $ alembic upgrade head
Reversión
(venv) $ alembic downgrade -1 # 回退到上一个版本
alembic upgrade headenheadrepresenta la última versión. También puedes especificar un número de versión concreto:alembic upgrade xxxx(ID de versión).
Comparación de herramientas de migración de los tres frameworks
| Operación | Django | Flask(Flask-Migrate) | FastAPI(Alembic) |
|---|---|---|---|
| Inicialización | No requiere | flask db init | alembic init alembic |
| Generar migración | makemigrations | flask db migrate -m "descripción" | alembic revision --autogenerate -m "descripción" |
| Ejecutar migración | migrate | flask db upgrade | alembic upgrade head |
| Reversión | migrate app 0001 | flask db downgrade | alembic downgrade -1 |
| Grado de automatización | Máximo | Medio | Requiere configurar manualmente env.py |
Resumen del capítulo
En este capítulo dominaste el flujo completo de Alembic: `alembic init` para inicializar, configurar `env.py` para conectar los modelos, `revision --autogenerate` para generar migraciones, `upgrade head` para ejecutarlas y `downgrade` para revertirlas.
Alembic requiere más pasos de configuración que las herramientas de migración de Django/Flask, pero es de más bajo nivel y más flexible.
Otras extensionesAvance del próximo capítulo: cuando haya muchos artículos, se necesitarán búsqueda y paginación. En el próximo capítulo se implementarán la búsqueda combinada por palabras clave y la paginación basada en offset/limit.