Ir al contenido
wannacode

Migraciones del esquema

En resumen: Una migración del esquema es un cambio numerado en el esquema de la base de datos que se ejecuta una sola vez y mantiene la base de datos en la misma versión en todas las máquinas.

Problema

«no such column: phone»

Un compañero añade una columna phone a customers en su computadora y escribe el código que la muestra. En su computadora todo funciona. La versión nueva sube al sitio y la página «Clientes» falla con no such column: phone, porque la base de datos del sitio no tiene esa columna. Y una tercera computadora del equipo tiene dos columnas, porque allí alguien la añadió a mano con otro nombre.

El código está en git y todos tienen la misma versión. El esquema de la base de datos necesita lo mismo: escrito, versionado e igual en todas partes.

La idea

Una migración: un cambio numerado

Una migración es un pequeño archivo SQL con un número. Cada cambio del esquema es un archivo nuevo, y los archivos están en git junto al código:

migrations/
001_create_shop.sql
002_reviews.sql
003_customers_phone.sql

La base de datos recuerda en una tabla cuáles se han ejecutado, normalmente schema_migrations. Al arrancar (o cuando se publica una versión nueva) la herramienta ejecuta, en orden, solo los archivos que todavía no están en ella. Esta base de datos está en la versión 2:

SQLbase de datos: tienda

La migración 3 es el cambio más su registro, juntos en una transacción:

SQLbase de datos: tienda

Ejecútala una segunda vez en el mismo cuadro y ALTER TABLE se detiene con «duplicate column name». Por eso la herramienta comprueba schema_migrations antes de ejecutar un archivo.

Míralo

Por qué en una transacción

Si una migración sin transacción se detiene a medias, el primer cambio se queda y falta el registro de la versión. El siguiente intento empieza otra vez desde el principio y tropieza con su propio primer paso. Aquí la segunda sentencia es un error (la misma columna dos veces):

SQLbase de datos: tienda

La transacción queda abierta con el primer ALTER TABLE, y el COMMIT nunca llega a la base de datos. Ejecuta ROLLBACK; en el cuadro y la columna phone desaparece: en SQLite y PostgreSQL un cambio de esquema forma parte de la transacción. Corriges el archivo y lo ejecutas de nuevo, y la base de datos está exactamente como estaba.

Pruébalo

Migración 3: puntos de fidelidad

Escribe la migración 3 para la base de datos en la versión 2: una columna loyalty_points en customers (un entero, obligatorio, 0 por defecto) y el registro (3, 'loyalty_points', '2026-10-25') en schema_migrations, en una transacción.

SQLbase de datos: tienda

La idea

Las herramientas

Nadie escribe a mano la comprobación de «qué migración se ha ejecutado». Cada lenguaje tiene una herramienta que lleva la tabla de versiones y ejecuta los archivos en orden:

  • Java: Flyway o Liquibase (V3__customers_phone.sql);
  • C#: EF Core Migrations (dotnet ef migrations add CustomersPhone) escribe la migración a partir del cambio en las clases;
  • Python: Alembic (para SQLAlchemy) o las migraciones de Django;
  • JavaScript: Prisma Migrate, Knex o node-pg-migrate.

Algunas escriben también un paso inverso (down) que deshace la migración. En un sitio con datos reales, volver atrás rara vez es un DROP COLUMN: si la columna nueva ya contiene datos, el paso inverso los pierde. Por eso «volver» suele ser una migración nueva hacia delante.

Míralo

Cambiar una base de datos en marcha: por pasos

El sitio no se detiene mientras se publica la nueva versión: durante un tiempo funcionan a la vez el código viejo y el nuevo. Si la migración renombra city a town, el código viejo falla en ese mismo segundo. Por eso el cambio se hace en tres pasos:

  1. Ampliar. Añadir town y rellenarla desde city. El código viejo no lo nota.
  2. Migrar. El código nuevo escribe en las dos y lee town. Esperas hasta que el código viejo haya desaparecido de todas partes.
  3. Contraer. Una migración aparte, posterior, quita city.
SQLbase de datos: tienda

Ejercicio

Nombre y apellido por separado

La tienda quiere saludar a los clientes por su nombre («Hola, Maria»). Haz el primer paso (ampliar): añade las columnas first_name y last_name a customers y rellénalas a partir de name (cada nombre son dos palabras separadas por un espacio). La columna name se queda.

SQLbase de datos: tienda

Test

Ponte a prueba

1. La migración 5 ya se ejecutó en el sitio. Tiene un error en el nombre de una columna. ¿Qué haces?
2. ¿Por qué una migración se ejecuta dentro de una transacción?
3. El sitio funciona sin parar y la columna city debe pasar a llamarse town. ¿Cuál es el orden seguro?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·