Skip to content

nkonev/r2dbc-migrate

Repository files navigation

R2DBC migration library

Maven Central Build Status

Inspired by this announcement. R2DBC page.

Supported databases

  • PostgreSQL
  • Microsoft SQL Server
  • H2
  • MariaDB
  • MySQL

It supports user-provided dialect. You can pass implementation of SqlQueries interface to the migrate() method. If you use Spring Boot, just define a bean of type SqlQueries. Example SimplePostgresqlDialect.

Features

  • No need the dedicated JDBC params, r2dbc-migrate reuses your R2DBC ConnectionFactory provided by Spring Boot
  • Convention-based file names, for example V3__insert_to_customers__split,nontransactional.sql
  • Reasonable defaults. By convention, in case Spring Boot SQL files should be placed in classpath:/db/migration/*.sql. It is configurable through r2dbc.migrate.resources-paths.
  • Pre-migration scripts, for example V0__create_schemas__premigration.sql. Those scripts are invoked every time before entire migration process(e. g. before migration tables created), so you need to make them idempotent. You can use zero or negative version number(s): V-1__create_schemas__nontransactional,premigration.sql. See example.
  • It waits until a database has been started, then performs test query, and validates its result. This can be useful for the initial data loading into database with docker-compose
  • Large SQL files support: migrations files larger than -Xmx: file will be split line-by-line (split modifier), then it will be loaded by chunks into the database. Example.
  • It supports lock, that make you able to start number of replicas your microservice, without care of migrations collide each other. Database-specific lock tracking issue.
  • Each migration runs in the separated transaction by default
  • It also supports nontransactional migrations, due to SQL Server 2017 prohibits CREATE DATABASE in the transaction
  • First-class Spring Boot integration, see example below
  • Also, you can use this library without Spring (Boot), see library example below
  • This library tends to be non-invasive, consequently it intentionally doesn't try to parse SQL and make some decisions relying on. So (in theory) you can freely update the database and driver's version
  • Two modes of picking migration files
    • index.html-like with explicit paths as in Liquibase - type JUST_FILE
    • directories-scanning like as in Flyway - type CONVENTIONALLY_NAMED_FILES

See the example in the two-modes branch https://github.com/nkonev/r2dbc-migrate-example/blob/two-modes/src/main/resources/application.yml#L15.

All available configuration options are in R2dbcMigrateProperties class. Their descriptions are available in your IDE Ctrl+Space help or in spring-configuration-metadata.json file.

Limitations

  • Currently, this library heavy relies on the upsert-like syntax like CREATE TABLE ... ON CONFLICT DO NOTHING. Because this syntax isn't supported in H2 in PostresSQL compatibility mode, as a result, this library can't be run against H2 with MODE=PostgreSQL. Use testcontainers with the real PostgreSQL.
  • Only forward migrations are supported. No backward migrations.
  • No checksum validation. As a result repeatable migrations aren't supported.

Compatibility (r2dbc-migrate, R2DBC Spec, Java, Spring Boot ...)

See here

Download

Spring Boot Starter

<dependency>
  <groupId>name.nkonev.r2dbc-migrate</groupId>
  <artifactId>r2dbc-migrate-spring-boot-starter</artifactId>
  <version>VERSION</version>
</dependency>

Only library

<dependency>
    <groupId>name.nkonev.r2dbc-migrate</groupId>
    <artifactId>r2dbc-migrate-core</artifactId>
    <version>VERSION</version>
</dependency>

If you use library, you need also use some implementation of r2dbc-migrate-resource-reader-api, for example:

<dependency>
    <groupId>name.nkonev.r2dbc-migrate</groupId>
    <artifactId>r2dbc-migrate-resource-reader-reflections</artifactId>
    <version>VERSION</version>
</dependency>

See Library example below.

Spring Boot example

https://github.com/nkonev/r2dbc-migrate-example

Spring Native example

See example here.

Library example

https://github.com/nkonev/r2dbc-migrate-example/tree/library