web-dev-qa-db-fra.com

Migrations de bases de données avec R2DBC

Je suis nouveau sur R2DBC ( https://r2dbc.io/ ). J'aimerais savoir si l'écosystème de r2dbc dispose d'un outil/cadre de migration de base de données.

Il semble que Liquibase & Flyway dépendent de JDBC. Existe-t-il un plan permettant à ces frameworks de prendre en charge un pilote r2dbc?

Toute entrée ou rétroaction est la bienvenue.

8
balteo

La réponse de Steve est correcte. R2DBC concerne principalement l'interaction avec les données réelles. Je voudrais ajouter une perspective différente.

Il est vrai qu'une API réactive n'apporte aucune amélioration lors des migrations. En fait, en y regardant de plus près, les migrations font partie du processus de démarrage qui est généralement synchrone, au moins synchronisé dans une certaine mesure.

Le fait d'exiger JDBC pour la migration ajoute à la complexité d'un tel arrangement d'application. Vous devez inclure un pilote JDBC dans une configuration R2DBC existante et vous devez configurer une autre connexion de base de données qui pointe vers la même base de données qu'avec R2DBC. Les deux exigences sont sujettes aux erreurs car elles doivent être configurées pour faire exactement la même chose.

De nos jours, les cadres de configuration d'application (Spring Boot, Micronaut, Quarkus) activent la fonctionnalité lorsqu'une certaine bibliothèque est disponible à partir du chemin de classe. Avoir un pilote JDBC configuré une fonctionnalité de démarrage qui n'est pas requise pour l'application mais requise lors du démarrage et qui est en quelque sorte un gaspillage de ressources.

Idéalement, vous configurez une technologie de connexion de base de données unique qui est réutilisée pour la migration de schéma et pour une interaction ultérieure des données au sein de votre application.

Par conséquent, il est logique de demander à Liquibase et Flyway de fournir une intégration basée sur R2DBC.

12
mp911de

Il ne me semble pas (d'un coup d'œil rapide à la première page de la page Web R2DBC) que les objectifs de R2DBC ont vraiment quelque chose à voir avec les migrations. Cette page répertorie les principales fonctionnalités comme suit:

  • Flux réactifs - R2DBC est fondé sur des flux réactifs fournissant une API non bloquante entièrement réactive.
  • Bases de données relationnelles - R2DBC engage les bases de données SQL avec une API réactive, ce qui n'est pas possible avec la nature bloquante de JDBC.
  • Solutions évolutives - Reactive Streams permet de passer de l'approche classique d'un thread par connexion à une approche plus puissante et plus évolutive.

Il n'y a rien là-dedans qui justifie d'ajouter le support R2DBC à un framework comme Liquibase. Les pilotes JDBC actuellement utilisés ne souffrent pas de leur utilisation d'une API non bloquante, n'ont pas vraiment besoin d'une "API réactive" et n'ont certainement pas besoin d'avoir plus d'un thread par connexion.

Les outils de migration concernent principalement la forme/structure de la base de données et non le contenu, tandis que R2DBC est destiné aux applications qui se soucient principalement des données réelles.

En résumé, je ne vois aucune raison pour laquelle quelqu'un n'utiliserait pas un outil de migration comme Liquibase qui utilise JDBC simplement parce que son application utilise R2DBC, et je ne vois aucun avantage à ajouter la prise en charge R2DBC à un outil comme Liquibase.

3
SteveDonie

Si quelqu'un est confronté au même problème et ne veut pas utiliser le maven-flyway-plugin, Jetez un œil à la classe FlywayAutoConfiguration. Il a @Conditional(FlywayDataSourceCondition.class), qui a @ConditionalOnBean(DataSource.class) à l'intérieur. Par conséquent, l'essentiel est que vous devez fournir un environnement de base de données non réactif pour faire fonctionner Flyway. La solution la plus simple consiste à faire quelque chose comme ceci:

@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();
    }
}

Je suis allé de cette façon car je ne voulais pas: 1) exécuter le plugin à chaque démarrage; 2) Passer les propriétés de la base de données dans la ligne de commande

0
Ivan Timoshin

Vous pouvez essayer mon package r2dbc-migrate .

En configuration minimale (supposons que vous utilisez Spring Boot 2.3.0.M3), ajoutez simplement

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

à pom.xml

puis ajoutez des fichiers .sql dans classpath, par exemple dans /db/migration/

puis ajouter

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

à votre application.yml

0
Nikita Konev

Les deux réponses ci-dessus sont correctes - je voulais juste ajouter que si vous cherchez un chemin rapide et facile et que vous utilisez maven, Flyway est probablement le moyen le plus pratique de fonctionner.

Tout ce dont vous avez besoin est un plugin Flyway Maven, deux dépendances pom et des scripts SQL de migration.

Par exemple. en supposant que spring - r2dbc - postgresql, vous pouvez préparer l'infrastructure de migration en trois étapes simples:

(1) Ajoutez un script de migration aux ressources:

resources/db/migration/V1_init.sql

(2) ajouter deux dépendances à pom

    <dependency>
        <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
    </dependency>

(3) et une définition de plugin dans la section build:

    <plugin>
        <groupId>org.flywaydb</groupId>
           <artifactId>flyway-maven-plugin</artifactId>
           <version>6.0.0-beta2</version>
    </plugin>

et maintenant vous avez une seule commande CLI maven pour migrer:

    mvn flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/test -Dflyway.user=test -Dflyway.password=test

Voir plus de documents sur les plugins Flyway maven ici

0
tomaszkubacki