leanmind logo leanmind text logo

Blog

BDD

Behaviour-driven Development es una técnica para tomar mejores requisitos de producto.

Migrando bases de datos con Flyway

Por Rubén Zamora

Recién comenzando el proyecto Huella positiva, he conocido Flyway, que algunos lo conoceréis ya, o a su congénere Liquibase, por nuestro compañero Jose (jrodalo), que escribió el artículo. Yo no he tenido la ocasión de probar a largo plazo ninguno de los dos, pero si os traigo este artículo para los casos en los que tengáis que elegir Flyway para configurarlo.

Pequeña intro sobre Flyway Flyway actualiza una base de datos de una versión a otra usando migraciones. Podemos escribir las migraciones en SQL con una sintaxis específica para la base de datos o en Java para transformaciones avanzadas de la base de datos.

Las migraciones pueden ser versionadas o repetidas. La primera tiene una versión única y se aplica exactamente una vez. La segunda no tiene una versión. En su lugar, se (re)aplican cada vez que cambia su suma de control.

Comenzamos Aquí dejo la configuración que voy hacer yo para generar el código necesario usando Spring-Boot que me lo genere ya Spring initializr

Generar el mismo proyecto con Spring Initializr

Usaré:

Se podría usar H2 para que se cree la base de datos en la memoria ram y sin necesidad de tirar de dockers, pero yo en esta ocasión voy a usar testContainers para asegurarme una compatibilidad del 100%.

Configuración

Añadimos la dependencia al pom.xml

1
2
3
4
<dependency>
	  <groupId>org.flywaydb</groupId>
	  <artifactId>flyway-core</artifactId>
</dependency>

Como bien comentaba Jose en su artículo, no es necesario indicar la versión, porque Spring Boot ya lo hace para nosotros gracias al spring-boot-starter-parent, en este caso es exactamente igual. Aunque yo para este ejemplo he utilizado la versión 5.2.4.

Spring Boot va a buscar los ficheros de migración de Flyway dentro de la ruta src/main/resources/db/migrations

Por lo que solo tendremos que crear en la carpeta 📁resources, un directorio llamado 📁db.migration, que él reconocerá como directorio por defecto de las migraciones

PD: Si has utilizado el Spring Initializr ya te lo habrá hecho solo.

Migraciones

Flyway usa SQL para las migraciones, ignoro si se puede usar otro formato para las migraciones de como los diferentes formatos que se pueden usar con liquidbase, pero en la documentación oficial no he encontrado nada relevante con esto.

Por otro lado, a diferencia de Liquisbase por lo que entiendo en el artículo de Jose, este (Flyway) si necesita de tener diferentes archivos versionados para que te coja los cambios, con que el número de versionado sea mayor da igual cómo lo pongas.

Si miramos la documentación oficial de Flyway, ya nos indica cómo hacer el naming

Ejemplo de cómo quedaría:

Directory structure

Ejecutando las migraciones

Las migraciones se ejecutan automáticamente al arrancar la aplicación. Spring Boot se encarga de ejecutar Flyway y este se encarga de revisar el estado de las migraciones. Si existen cambios, los ejecutará por nosotros.

De esta forma, si necesitamos añadir una nueva tabla o campo a nuestra base de datos, solo debemos añadir la migración y desplegar los cambios.

Añadiendo Testcontainers

Página oficial - Testcontainers

Haré hincapié en lo que dicen en la documentación oficial de TestContainer de por qué usarlo.

Los contenedores de prueba no tienen un rendimiento tan alto como el H2, pero te dan el beneficio de una compatibilidad del 100% con la base de datos (ya que ejecuta una base de datos real dentro de un contenedor).

Por lo que ahora, para probar que esto funciona, vamos a tirar de un TestContainers.

Metemos las dependencia en nuestro pom.xml:

1
2
3
4
5
6
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>
    <version>1.13.0</version>
    <scope>test</scope>
</dependency>

En nuestro archivo de configuración para test (src/test/resources), añadimos la configuración para PostgreSQL:

application.properties

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
## Postgres
spring.datasource.platform=postgres
spring.datasource.username=root
spring.datasource.password=12345
## Configuración necesaria para test container
spring.datasource.url=jdbc:tc:postgresql:12.2:///flywaytest
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver

## JPA
spring.jpa.hibernate.ddl-auto=create

Nota: driver-class-name solo es necesario para versiones de Spring Boot anteriores a la 2.3.0

Lo siguiente sería crear un test de integración con @SpringBootTest e intentar acceder a nuestra nueva tabla, algo como esto valdría:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class FlywayTests {

	@Autowired
	JpaProductRepository productRepository;

	@Test
	void creates_database_tables_using_migrations() {
		Product product = Product.builder()
				.name("Test Product")
				.build();

		Product insertedProduct = productRepository.save(product);
		Product selectProduct = productRepository.findById(insertedProduct.getId())
				.orElse(null);

		assertThat(product.getName(), is(selectProduct.getName()));

	}

}

Lanzamos el test y verificamos que se levantan los contenedores y pasa correctamente.

Launching tests

Finalmente, por si quieren ver el código en general, os dejo enlace al repositorio

🐱 GitHub - flyway-springboot-testcontainer

Publicado el 18/08/2021 por

¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.

Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?

Impulsamos el crecimiento profesional de tu equipo de developers