Crear migraciones de bases de datos y modelos ORM desde un contrato de entidades puede automatizarse con Cursor si configuras bien el contexto y la documentación indexada. Aquí verás cómo llevar las specs al contenedor, indexar Alembic y SQLAlchemy, y guiar al asistente paso a paso para que genere migraciones, modelos y seeds alineados con tu contrato.
Esta guía es útil si trabajas con Python, Docker y un workflow asistido por IA, y necesitas que la generación de código respete tu arquitectura sin saltarse pasos críticos como la reconstrucción de la imagen.
¿Cómo preparar el contenedor para que Cursor vea las specs?
El primer obstáculo es que el editor corre dentro del contenedor de Docker, así que cualquier archivo de contrato debe estar visible ahí. Si la carpeta specs no está montada, Cursor no puede usarla como contexto [00:32].
La solución tiene dos ajustes paralelos:
- En el
Dockerfile, copia la carpeta specs dentro de specs de la imagen.
- En el
docker-compose, agrega el volumen app/specs para que los cambios se reflejen sin reconstruir cada vez.
Después corres make stop, make build y make start, y vuelves a hacer attach al contenedor. Al revisar la carpeta API, las specs ya aparecen disponibles para el chat de Cursor.
¿Por qué los archivos de contrato deben estar dentro del contenedor? Porque Cursor solo puede leer lo que vive en el editor activo. Si las specs quedan fuera del volumen de Docker, el modelo no las verá como contexto y generará código sin alinearse al contrato.
¿Cómo indexar la documentación de Alembic y SQLAlchemy en Cursor?
Antes de pedirle migraciones a Cursor, conviene indexar la documentación oficial para que las respuestas se basen en la API real y no en suposiciones [02:20].
En Settings > Indexing and Docs agregas una nueva fuente pegando la URL de la documentación. Cursor hace scrapping y detecta el nombre. Cuando indexas Alembic, el sistema lo etiqueta como SQLAlchemy porque Alembic es parte del proyecto, así que renómbralo manualmente como Alembic para distinguirlo. Repite el proceso con SQLAlchemy ORM como segunda entrada.
Con ambas referencias indexadas, en el chat puedes invocarlas con el símbolo de documentación y forzar que Cursor use esas fuentes al planear los pasos.
¿Cómo guiar a Cursor para crear migraciones sin romper el flujo de Docker?
El prompt inicial debe pedir análisis y planificación, no ejecución directa. Le indicas que en contracts están las entidades, que cada una debe convertirse en tabla con sus atributos, y que use Alembic para las migraciones [04:10].
Cursor responde con una lista de pasos. El primero suele ser la configuración inicial: instalar Alembic y actualizar pyproject.toml. Aquí entra una corrección importante: no debe usar pip ni ejecutar la instalación, solo agregar la dependencia en pyproject.toml. La instalación real ocurre cuando se reconstruye la imagen.
El flujo queda así:
- Pides ejecutar únicamente el paso uno.
- Aceptas el cambio en
pyproject.toml.
- Sales del contenedor y corres
make stop, make build, make start.
- Vuelves a hacer attach y verificas con
alembic en la terminal que el binario responde.
Una vez confirmada la instalación, le dices a Cursor que omita el uv sync y continúe con el resto. El asistente crea el esqueleto de versiones, el archivo alembic.ini y modifica env.py para conectar las migraciones.
¿Por qué no instalar Alembic con pip dentro del contenedor? Porque el entorno se gestiona con uv y la instalación debe quedar registrada en la imagen de Docker. Si lo haces manualmente dentro del contenedor, el cambio se pierde al reconstruir.
¿Qué hacer si Alembic se crea fuera del volumen montado?
Un detalle común: Cursor genera los archivos de Alembic en la raíz del contenedor, pero esa ruta no está montada como volumen, así que fuera del contenedor no aparecen [07:40]. Le pides explícitamente que mueva todos los archivos de Alembic dentro de la carpeta App, que sí está en el volumen. Tras el movimiento, revisas los diffs: en uno corrige la importación de App y en otro ajusta la referencia para invocar solo el core. Aceptas ambos cambios.
¿Qué genera Cursor al crear los modelos de SQLAlchemy?
Con la base lista, le pides continuar y aplicar todos los pasos restantes. La ejecución toma tiempo porque toca varios archivos, pero el resumen final muestra una implementación completa [09:30].
Lo más interesante es la abstracción que propone:
- Un
BaseModel con campos de auditoría: id, created_at, updated_at y deleted_at.
- Un modelo
Teacher que hereda de BaseModel y solo añade name, email y la relación con cursos.
- Un modelo
Course con su relación a profesores y a clases.
- Un modelo
Lesson en lugar de Class, porque Class es una palabra reservada en Python.
Ese cambio de Class a Lesson lo detecta Cursor solo, durante el chat, y crea un archivo nuevo manteniendo los atributos definidos en el contrato. La relación entre Course y Lesson se resuelve por la tabla intermedia correspondiente.
¿Qué incluye la migración generada y los seeds de desarrollo?
La migración inicial crea las tablas Teachers, Courses y Lessons con sus campos, los constraints y los campos de auditoría heredados [11:50]. Además, Cursor genera un archivo seed con datos de ejemplo: varios profesores, cursos asociados a esos profesores y clases vinculadas a cada curso. El seed hace commit e imprime confirmación.
Como cierre, el asistente entrega un dump estilo bitácora en formato Markdown dentro de la carpeta db, más un README adicional explicando los pasos. Esa documentación queda dentro del proyecto y evita que el conocimiento del proceso se pierda.
El reto queda abierto: haz que esos seeds se ejecuten automáticamente al construir la imagen de Docker, para que cualquier entorno local arranque con datos listos. Cuéntame en los comentarios cómo lo resolviste.