07 - Migraciones: Flyway
El esquema evoluciona con el código: en cada cambio se crean tablas, se añaden columnas, se ajustan índices. Si cada entorno — el servidor local de cada desarrollador, el contenedor de pruebas, el despliegue — ejecuta sus DDL a mano, acaban desincronizados y «funciona aquí» deja de garantizarse. Las migraciones versionadas versionan el esquema junto al código; Flyway las aplica en orden.
1. Una migración
Un fichero SQL por cambio, con su versión y una descripción en el nombre:
src/main/resources/db/migration/ ├── V1__create_publisher_and_book.sql ├── V2__add_book_author_table.sql └── V3__add_stock_column.sql
| Regla | Motivo |
|---|---|
| La versión fija el orden | El esquema evoluciona paso a paso, igual en todos los entornos |
| Solo SQL del motor (DDL, y DML si procede) | Se ejecuta tal cual contra MariaDB, sin traducción |
| Inmutabilidad: una aplicada no se toca | Ya se aplicó en otros entornos; el siguiente cambio es una migración nueva |
2. Cómo funciona
Al arrancar, Flyway busca los scripts en el classpath, los ordena por versión y los compara con la tabla flyway_schema_history (la crea la primera vez): aplica solo los pendientes y registra cada uno con su checksum, que detecta cualquier modificación sobre un script ya aplicado.
| Columna | Guarda |
|---|---|
version | La versión aplicada (1, 2…) |
description | La del nombre del fichero |
checksum | La firma del contenido: cambiar el fichero falla |
3. Aplicarlas en el proyecto
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>11.7.2</version> </dependency>
Flyway.configure()
.dataSource(url, username, password)
.load()
.migrate();
migrate() se ejecuta al arrancar la aplicación, antes de la primera conexión del pool (tema 06): así el esquema que existe corresponde siempre al código que corre. Como alternativa, el plugin de Maven permite ejecutar mvn flyway:migrate desde la línea de comandos.
4. El mismo esquema en todos lados
- Desarrollo: cada cambio añade una migración
V(n+1); al arrancar se aplica en local. - Pruebas: el contenedor de Testcontainers arranca vacío y aplica las mismas migraciones (se describe en el tema de pruebas de integración de Entornos): el esquema probado es exactamente el del proyecto.
- Despliegue: las mismas migraciones contra el servidor real.