Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Database migrations with R2DBC

I am new to R2DBC (https://r2dbc.io/). I would like to know whether r2dbc's ecosystem has a database migration tool/framework.

It seems Liquibase & Flyway depend on JDBC. Is there a plan for allowing those frameworks to support a r2dbc driver?

Any input or feedback welcome.

like image 911
balteo Avatar asked Jul 24 '19 12:07

balteo


2 Answers

You can try my package r2dbc-migrate.

In minimal configuration (let's suppose that you are using Spring Boot 2.3.0.M3), just add

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

to pom.xml

then add .sql files in classpath, for example in /db/migration/

then add

r2dbc.migrate.resourcesPath: classpath:/db/migration/*.sql

to your application.yml

like image 101
Nikita Konev Avatar answered Nov 07 '22 03:11

Nikita Konev


If anyone face the same problem and doesn't want to use the maven-flyway-plugin, take a look at the FlywayAutoConfiguration class. It has @Conditional(FlywayDataSourceCondition.class), which has @ConditionalOnBean(DataSource.class) inside. Therefore the bottom line is you should provide a non-reactive database environment to make Flyway work. The most straight forward solution is to do something like this:

@Configuration
public class DataBaseConfig extends AbstractR2dbcConfiguration {

    @Value("${spring.data.postgres.host}")
    private String host;
    @Value("${spring.data.postgres.port}")
    private int port;
    @Value("${spring.data.postgres.database}")
    private String database;
    @Value("${spring.data.postgres.username}")
    private String username;
    @Value("${spring.data.postgres.password}")
    private String password;

    @Bean
    public DatabaseClient databaseClient() {
        return DatabaseClient.create(connectionFactory());
    }

    @Bean
    @Override
    public PostgresqlConnectionFactory connectionFactory() {
        PostgresqlConnectionConfiguration config = PostgresqlConnectionConfiguration.builder()
                .host(host)
                .port(port)
                .database(database)
                .username(username)
                .password(password)
                .build();
        return new PostgresqlConnectionFactory(config);
    }

    @Bean
    public DataSource dataSource() {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName("org.postgresql.Driver");
        dataSourceBuilder.url("jdbc:postgresql://" + host + ":" + port + "/" + database);
        dataSourceBuilder.username(username);
        dataSourceBuilder.password(password);
        return dataSourceBuilder.build();
    }
}

I went this way as I didn't want to: 1) Run the plugin on each startup; 2) Pass database properties in the comand line

like image 45
Ivan Timoshin Avatar answered Nov 07 '22 04:11

Ivan Timoshin