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.
Steve's answer is correct hat R2DBC is primarily about interaction with the actual data. I'd like to add a different perspective.
It's true that a reactive API does not provide any improvement during migrations. In fact, looking closely, migrations are part of the startup process which is typically synchronous, at least synchronized to some extent.
Requiring JDBC for migration adds to complexity in such an application arrangement. You are required to include a JDBC driver to an existing R2DBC setup and you need to configure another database connection that points to the same database as with R2DBC. Both requirements are error-prone as they need to be configured to do the exact same thing.
Nowadays, application configuration frameworks (Spring Boot, Micronaut, Quarkus) activate functionality when a certain library is available from the classpath. Having a JDBC driver configured boots functionality that isn't required for the application but required during bootstrapping and that is sort of a waste of resources.
Ideally, you configure a single database connection technology that is reused for schema migration and for later data interaction within your application.
Therefore it makes sense to ask Liquibase and Flyway to provide an R2DBC-based integration.
It doesn't seem to me (from an admittedly cursory glance at the front page of the R2DBC web page) that the goals of R2DBC really have anything to do with migrations. That page lists key features as:
There is nothing in there that warrants adding R2DBC support to a framework like Liquibase. The JDBC drivers currently in use don't suffer from their use of a non-blocking API, don't really need a "reactive API", and almost certainly don't need to have more than one thread per connection.
Migration tools are primarily concerned with the shape/structure of the database and not the contents, while R2DBC is aimed at applications that primarily care about the actual data.
In Summary, I don't see any reason why someone wouldn't use a migration tool like Liquibase that uses JDBC just because their application uses R2DBC, and I don't see any advantage to adding R2DBC support to a tool like Liquibase.
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
Both answers above are correct - just wanted to add that if you are looking for fast and easy path and you are using maven then Flyway is probably the most convenient way to operate.
All you need to have is Flyway Maven plugin, two pom dependencies and migration sql scripts.
Eg. assuming spring - r2dbc - postgresql you can have migration infrastructure ready in just three simple steps:
(1) Add migration script to resources:
resources/db/migration/V1_init.sql
(2) add two dependencies to pom
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
(3) and one plugin definition in build section:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>6.0.0-beta2</version>
</plugin>
and now you have single maven CLI command to migrate:
mvn flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/test -Dflyway.user=test -Dflyway.password=test
See more Flyway maven plugin docs here
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
Please, there is a solution for that finally, at least a temporary solution, because there is no Flyway official solution yet (I believe soon we are gonna see a official version).
Please check my post: https://stackoverflow.com/a/62864838/7681696
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.