Retour aux articles

Gérer les migrations de schémas de base de données PostgreSQL avec Flyway/Liquibase en Spring Boot

Gérer les migrations de schémas de base de données PostgreSQL avec Flyway/Liquibase en Spring Boot | Laty Gueye Samba - Développeur Full Stack Dakar Sénégal, Expert Java Spring Boot Angular
```html Gérer les migrations de schémas PostgreSQL avec Flyway/Liquibase en Spring Boot

Gérer les migrations de schémas PostgreSQL avec Flyway/Liquibase en Spring Boot

Les schémas de base de données évoluent en permanence : ajout de colonnes, refactorisation, création de tables, procédures ou vues. Pour maîtriser ces changements, les migrations doivent être versionnées, reproductibles et déployables sur plusieurs environnements. Dans un contexte Spring Boot, Flyway et Liquibase constituent deux approches éprouvées pour automatiser le cycle de vie des scripts SQL et des changements de schéma, en particulier pour PostgreSQL.

Pourquoi utiliser un outil de migration

Sans outil de migration, les déploiements finissent souvent par dépendre d’instructions manuelles : exécution de scripts dans un ordre implicite, corrections en production, dérives de versions et risques d’incohérence. Flyway et Liquibase imposent une discipline :

• Historique des changements appliqués
• Contrôle de l’ordre d’exécution
• Détection d’écarts (migrations manquantes ou modifiées)
• Déploiement reproductible via CI/CD

Choisir entre Flyway et Liquibase

Flyway et Liquibase répondent à un besoin similaire, mais avec des philosophies différentes. Le choix peut se faire selon l’organisation de l’équipe, les pratiques de validation et la structure attendue des scripts.

Flyway : approche pragmatique, simple à mettre en place, basée sur des fichiers nommés de manière conventionnelle (ex. V1__init.sql). L’historique est géré de façon explicite, et l’exécution suit une séquence.

Liquibase : approche orientée “changeSets”, supportant davantage de modélisation (YAML/XML/JSON) et d’abstractions au-delà du pur SQL. La gestion des dépendances et le contrôle fin peuvent être appréciés dans des architectures plus complexes.

Intégration dans Spring Boot

Dans un projet Spring Boot, l’intégration se fait généralement via une configuration applicative. À l’exécution, l’outil exécute les migrations automatiquement au démarrage (selon le paramétrage), ou via des commandes dédiées.

Flyway avec PostgreSQL dans Spring Boot

Configuration Maven/Gradle

Pour Flyway, une dépendance dédiée est ajoutée, puis l’outil est configuré via application.yml ou application.properties.

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

Configuration applicative

Exemple de configuration (PostgreSQL en environnement de production).

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/appdb
    username: appuser
    password: secret
  flyway:
    enabled: true
    locations: classpath:db/migration
    baseline-on-migrate: true

Structuration des migrations Flyway

Les scripts SQL doivent être placés dans un dossier tel que db/migration. Le nom suit un schéma basé sur le numéro de version.

Exemples :

src/main/resources/db/migration/
  V1__create_tables.sql
  V2__add_indexes.sql
  V3__modify_columns.sql

Exemple de script SQL Flyway

-- V2__add_indexes.sql
CREATE INDEX IF NOT EXISTS idx_orders_customer_id
ON orders (customer_id);

Il est recommandé d’utiliser IF NOT EXISTS quand c’est pertinent, afin de limiter le risque d’erreurs lors de reruns, tout en conservant une discipline forte sur la version et l’intégrité des scripts.

Liquibase avec PostgreSQL dans Spring Boot

Dépendance et configuration

Liquibase requiert une dépendance liquibase-core (ou l’autoconfiguration via Spring Boot), puis la configuration des emplacements des changeSets.

<dependency>
  <groupId>org.liquibase</groupId>
  <artifactId>liquibase-core</artifactId>
  <version>REPLACE_WITH_VERSION</version>
</dependency>

Exemple application.yml pour Liquibase

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/appdb
    username: appuser
    password: secret
  liquibase:
    enabled: true
    change-log: classpath:db/changelog/db.changelog-master.xml

Structuration des changeSets Liquibase

Liquibase organise les modifications via des changeSets. Chaque changeSet possède un identifiant et s’exécute une seule fois.

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
  xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
     http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.20.xsd">

  <changeSet id="2026-01-01-01" author="team">
    <createTable tableName="orders">
      <column name="id" type="BIGSERIAL"></column>
      <column name="customer_id" type="BIGINT"></column>
    </createTable>
  </changeSet>
</databaseChangeLog>

La granularité des changeSets permet de documenter l’intention, de versionner la logique métier et de réduire les risques lors des migrations progressives.

Bonnes pratiques pour PostgreSQL

Planifier les changements et leur impact

Pour PostgreSQL, l’impact sur la performance et la disponibilité doit être évalué. Les opérations lourdes (rebuild d’index, tables volumineuses) peuvent nécessiter :

des stratégies par lot
des fenêtres de déploiement
l’ajout d’index de manière contrôlée
l’usage de contraintes compatibles avec la migration

Rendre les migrations idempotentes (quand nécessaire)

L’idempotence complète dépend de la stratégie de l’outil. Néanmoins, lorsque cela est utile, les clauses IF EXISTS et IF NOT EXISTS peuvent sécuriser certaines opérations (notamment pour les index ou objets optionnels).

Éviter la modification de migrations “publiées”

Une migration déjà appliquée ne devrait pas être modifiée. En cas d’erreur, une nouvelle migration est créée. Cette discipline évite les divergences d’historiques entre environnements.

Utiliser une base de données de test

Pour valider rapidement la cohérence des scripts, une stratégie courante consiste à utiliser une base de test. Un exemple consiste à employer H2 pour exécuter les migrations en CI, avec prudence toutefois : H2 n’imite pas parfaitement PostgreSQL (types, dialecte SQL, comportements spécifiques). L’étape finale de validation doit inclure PostgreSQL.

Exemple de test de migration avec H2 (principe)

-- Exemple : exécution en CI avec une base H2 séparée pour détecter les erreurs de syntaxe
-- La validation finale doit être répétée sur PostgreSQL avant déploiement.

Stratégie CI/CD : exécution et contrôle

Exécution au démarrage vs commande dédiée

L’exécution des migrations peut être déclenchée au démarrage de l’application ou via un pas dédié dans le pipeline. La seconde option facilite parfois la séparation des responsabilités : base prête, puis application déployée.

Contrôle des échecs

Les échecs doivent bloquer le déploiement. L’historique des migrations (table Flyway ou Liquibase) doit être inspectable. En cas d’incohérence, une procédure de correction (nouvelle migration) doit être appliquée.

Comparatif rapide

Flyway convient très bien aux équipes qui préfèrent des scripts SQL versionnés simplement et une exécution séquentielle claire. Liquibase est particulièrement utile lorsque la modélisation des changements et la gestion fine des changeSets sont prioritaires.

Dans tous les cas, la priorité reste identique : assurer la traçabilité, prévenir la dérive des schémas et rendre chaque déploiement fiable.

Conclusion

En environnement Spring Boot avec PostgreSQL, Flyway et Liquibase apportent une base solide pour gérer les évolutions du schéma. En appliquant des règles strictes de versioning, en testant les migrations (avec attention particulière à H2 pour la CI) et en validant sur PostgreSQL avant production, la plateforme réduit fortement les risques d’erreurs et améliore la fiabilité du cycle de déploiement.

À propos de l'auteur

Laty Gueye Samba est développeur Full Stack basé à Dakar, Sénégal. Spécialiste des écosystèmes Java / Spring Boot et Angular.

Contact : latygueyesamba@gmail.com  |  Dakar, Sénégal