使用 R2DBC 进行数据库迁移
Database migrations with R2DBC
我是 R2DBC 的新手 (https://r2dbc.io/)。想知道r2dbc的生态有没有数据库迁移tool/framework.
Liquibase 和 Flyway 似乎依赖于 JDBC。是否有计划允许这些框架支持 r2dbc 驱动程序?
欢迎任何意见或反馈。
在我看来(粗略地浏览了 R2DBC 网页的首页)R2DBC 的目标与迁移没有任何关系。该页面将主要功能列为:
- Reactive Streams - R2DBC 建立在 Reactive Streams 之上,提供完全反应式的非阻塞 API。
- 关系数据库 - R2DBC 使用 SQL 具有反应性 API 的数据库,JDBC.
的阻塞性质不可能做到这一点
- 可扩展的解决方案 - Reactive Streams 使得从经典的每个连接一个线程的方法转变为更强大、更具可扩展性的方法成为可能。
其中没有任何内容可以保证向 Liquibase 这样的框架添加 R2DBC 支持。当前使用的 JDBC 驱动程序不会因为使用非阻塞 API 而受到影响,不需要 "reactive API",而且几乎肯定不需要更多每个连接超过一个线程。
迁移工具主要关注数据库的 shape/structure 而不是内容,而 R2DBC 针对的是主要关注实际数据的应用程序。
总而言之,我没有看到任何人不使用像 Liquibase 这样使用 JDBC 的迁移工具的任何理由,只是因为他们的应用程序使用 R2DBC,而且我没有看到添加任何优势R2DBC 支持像 Liquibase 这样的工具。
Steve 的回答是正确的,R2DBC 主要是关于与实际数据的交互。我想补充一个不同的观点。
确实,反应式 API 在迁移过程中没有提供任何改进。事实上,仔细观察,迁移是启动过程的一部分,通常是同步的,至少在某种程度上是同步的。
需要 JDBC 进行迁移会增加此类应用程序安排的复杂性。您需要将 JDBC 驱动程序包含到现有的 R2DBC 设置中,并且您需要配置另一个指向与 R2DBC 相同的数据库的数据库连接。这两个要求都容易出错,因为它们需要配置为执行完全相同的操作。
如今,应用程序配置框架(Spring Boot、Micronaut、Quarkus)会在类路径中提供某个库时激活功能。让 JDBC 驱动程序配置引导功能,应用程序不需要但在引导过程中需要,这是一种资源浪费。
理想情况下,您配置一个单一的数据库连接技术,该技术可重复用于模式迁移和应用程序中的以后数据交互。
以上两个答案都是正确的 - 只是想补充一点,如果您正在寻找快速简便的途径并且您正在使用 Maven,那么 Flyway 可能是最方便的操作方式。
您只需要 Flyway Maven 插件、两个 pom 依赖项和迁移 sql 脚本。
例如。假设 spring - r2dbc - postgresql 您只需三个简单的步骤就可以准备好迁移基础设施:
(1) 添加迁移脚本到资源:
resources/db/migration/V1_init.sql
(2)在pom中添加两个依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
(3) 和构建部分中的一个插件定义:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>6.0.0-beta2</version>
</plugin>
现在您只有一个 maven CLI 命令可以迁移:
mvn flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/test -Dflyway.user=test -Dflyway.password=test
查看更多 Flyway maven 插件文档 here
如果有人遇到同样的问题并且不想使用 maven-flyway-plugin
,请查看 FlywayAutoConfiguration
class。它有@Conditional(FlywayDataSourceCondition.class)
,里面有@ConditionalOnBean(DataSource.class)
。因此底线是你应该提供一个非反应性数据库环境来使 Flyway 工作。最直接的解决方案是做这样的事情:
@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();
}
}
我不想这样:
1) 运行 每次启动时的插件;
2) 在命令行中传递数据库属性
你可以试试我的包裹r2dbc-migrate。
在最小配置中(假设您使用的是 Spring Boot 2.3.0.M3),只需添加
<dependency>
<groupId>name.nkonev.r2dbc-migrate</groupId>
<artifactId>r2dbc-migrate-spring-boot-starter</artifactId>
<version>0.0.24</version>
</dependency>
到pom.xml
然后在类路径中添加 .sql 文件,例如在 /db/migration/
然后添加
r2dbc.migrate.resourcesPath: classpath:/db/migration/*.sql
给你的application.yml
拜托,终于有解决办法了,至少是临时解决办法,因为目前还没有Flyway官方的解决办法(相信很快就会有正式版)。
请检查我的post:
我是 R2DBC 的新手 (https://r2dbc.io/)。想知道r2dbc的生态有没有数据库迁移tool/framework.
Liquibase 和 Flyway 似乎依赖于 JDBC。是否有计划允许这些框架支持 r2dbc 驱动程序?
欢迎任何意见或反馈。
在我看来(粗略地浏览了 R2DBC 网页的首页)R2DBC 的目标与迁移没有任何关系。该页面将主要功能列为:
- Reactive Streams - R2DBC 建立在 Reactive Streams 之上,提供完全反应式的非阻塞 API。
- 关系数据库 - R2DBC 使用 SQL 具有反应性 API 的数据库,JDBC. 的阻塞性质不可能做到这一点
- 可扩展的解决方案 - Reactive Streams 使得从经典的每个连接一个线程的方法转变为更强大、更具可扩展性的方法成为可能。
其中没有任何内容可以保证向 Liquibase 这样的框架添加 R2DBC 支持。当前使用的 JDBC 驱动程序不会因为使用非阻塞 API 而受到影响,不需要 "reactive API",而且几乎肯定不需要更多每个连接超过一个线程。
迁移工具主要关注数据库的 shape/structure 而不是内容,而 R2DBC 针对的是主要关注实际数据的应用程序。
总而言之,我没有看到任何人不使用像 Liquibase 这样使用 JDBC 的迁移工具的任何理由,只是因为他们的应用程序使用 R2DBC,而且我没有看到添加任何优势R2DBC 支持像 Liquibase 这样的工具。
Steve 的回答是正确的,R2DBC 主要是关于与实际数据的交互。我想补充一个不同的观点。
确实,反应式 API 在迁移过程中没有提供任何改进。事实上,仔细观察,迁移是启动过程的一部分,通常是同步的,至少在某种程度上是同步的。
需要 JDBC 进行迁移会增加此类应用程序安排的复杂性。您需要将 JDBC 驱动程序包含到现有的 R2DBC 设置中,并且您需要配置另一个指向与 R2DBC 相同的数据库的数据库连接。这两个要求都容易出错,因为它们需要配置为执行完全相同的操作。
如今,应用程序配置框架(Spring Boot、Micronaut、Quarkus)会在类路径中提供某个库时激活功能。让 JDBC 驱动程序配置引导功能,应用程序不需要但在引导过程中需要,这是一种资源浪费。
理想情况下,您配置一个单一的数据库连接技术,该技术可重复用于模式迁移和应用程序中的以后数据交互。
以上两个答案都是正确的 - 只是想补充一点,如果您正在寻找快速简便的途径并且您正在使用 Maven,那么 Flyway 可能是最方便的操作方式。
您只需要 Flyway Maven 插件、两个 pom 依赖项和迁移 sql 脚本。
例如。假设 spring - r2dbc - postgresql 您只需三个简单的步骤就可以准备好迁移基础设施:
(1) 添加迁移脚本到资源:
resources/db/migration/V1_init.sql
(2)在pom中添加两个依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
(3) 和构建部分中的一个插件定义:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>6.0.0-beta2</version>
</plugin>
现在您只有一个 maven CLI 命令可以迁移:
mvn flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/test -Dflyway.user=test -Dflyway.password=test
查看更多 Flyway maven 插件文档 here
如果有人遇到同样的问题并且不想使用 maven-flyway-plugin
,请查看 FlywayAutoConfiguration
class。它有@Conditional(FlywayDataSourceCondition.class)
,里面有@ConditionalOnBean(DataSource.class)
。因此底线是你应该提供一个非反应性数据库环境来使 Flyway 工作。最直接的解决方案是做这样的事情:
@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();
}
}
我不想这样: 1) 运行 每次启动时的插件; 2) 在命令行中传递数据库属性
你可以试试我的包裹r2dbc-migrate。
在最小配置中(假设您使用的是 Spring Boot 2.3.0.M3),只需添加
<dependency>
<groupId>name.nkonev.r2dbc-migrate</groupId>
<artifactId>r2dbc-migrate-spring-boot-starter</artifactId>
<version>0.0.24</version>
</dependency>
到pom.xml
然后在类路径中添加 .sql 文件,例如在 /db/migration/
然后添加
r2dbc.migrate.resourcesPath: classpath:/db/migration/*.sql
给你的application.yml
拜托,终于有解决办法了,至少是临时解决办法,因为目前还没有Flyway官方的解决办法(相信很快就会有正式版)。
请检查我的post: