Aller au contenu principal

Migrations avec Flyway

Notions théoriques

Pourquoi gérer les migrations de base de données ?

Quand une application évolue, la structure de sa base de données change : nouvelles tables, nouvelles colonnes, modifications de contraintes. Sans outil de migration, chaque développeur doit appliquer manuellement les modifications SQL, ce qui entraîne des incohérences entre les environnements (dev, test, production).

Flyway résout ce problème en versionnant les scripts SQL exactement comme Git versionne le code source.

Comparaison avec Doctrine Migrations
Doctrine Migrations (Symfony)Flyway (Spring Boot)
php bin/console make:migrationCréer manuellement V2__description.sql
php bin/console doctrine:migrations:migrateAutomatique au démarrage de l'application
Table doctrine_migration_versionsTable flyway_schema_history
Fichiers migrations/VersionXXXX.phpFichiers db/migration/VN__description.sql

Ajouter Flyway au projet

Dans pom.xml, ajoutez la dépendance :

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

Convention de nommage des scripts

Les fichiers de migration sont placés dans src/main/resources/db/migration/ et respectent la convention :

V{numéro}__{description}.sql
  • V : préfixe obligatoire (V majuscule)
  • {numéro} : numéro de version entier croissant (1, 2, 3...)
  • __ : deux underscores séparent le numéro de la description
  • {description} : description en snake_case (mots séparés par _)

Exemples valides :

V1__init.sql
V2__add_resume_article.sql
V3__create_table_utilisateurs.sql
V4__add_index_email_utilisateur.sql
Ne jamais modifier un script déjà exécuté

Une fois qu'un script Flyway a été exécuté en production, ne le modifiez jamais. Flyway stocke le checksum (empreinte) de chaque fichier dans flyway_schema_history. Si vous modifiez un fichier déjà exécuté, Flyway refusera de démarrer et lancera une erreur Validate failed. Pour modifier une table existante, créez un nouveau script V2__....

La table flyway_schema_history

À son premier démarrage, Flyway crée automatiquement une table flyway_schema_history qui enregistre chaque migration exécutée :

installed_rankversiondescriptionscriptchecksumsuccess
11initV1__init.sql-1234567true
22add resume articleV2__add_resume_article.sql8765432true

Au prochain démarrage, Flyway compare les fichiers SQL présents avec ceux déjà exécutés et n'exécute que les nouveaux.

Configuration avec spring.jpa.hibernate.ddl-auto

Avec Flyway, il faut désactiver la génération automatique de schéma par Hibernate et utiliser validate à la place :

# src/main/resources/application.properties ou application.yml
spring.jpa.hibernate.ddl-auto=validate
ValeurComportement
createSupprime et recrée le schéma au démarrage (réservé aux premiers tests)
create-dropCrée au démarrage, supprime à l'arrêt
updateModifie le schéma existant (dangereux en prod)
validateVérifie que le schéma SQL correspond aux entités Java (sans modifier)
noneNe fait rien
Ne jamais utiliser ddl-auto=create en production

create ou update peuvent supprimer des données ou modifier le schéma de façon imprévue. Avec Flyway, utilisez validate : Hibernate vérifie que votre base correspond à vos entités et lève une erreur au démarrage si ce n'est pas le cas.

Exemples de scripts de migration

V1__init.sql — Création initiale des tables :

CREATE TABLE articles (
id BIGINT NOT NULL AUTO_INCREMENT,
titre VARCHAR(255) NOT NULL,
contenu TEXT NOT NULL,
date_creation DATETIME,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE utilisateurs (
id BIGINT NOT NULL AUTO_INCREMENT,
email VARCHAR(180) NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(50),
PRIMARY KEY (id),
UNIQUE KEY uk_utilisateurs_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

V2__add_resume_article.sql — Ajouter une colonne :

ALTER TABLE articles
ADD COLUMN resume VARCHAR(500) AFTER titre;

Vérifier l'état des migrations

# Afficher l'état des migrations (version, description, date d'exécution)
mvn flyway:info

Exemple pratique

Structure complète d'un projet MonBlog avec Flyway :

src/main/resources/
├── application.properties
└── db/
└── migration/
├── V1__init.sql
└── V2__add_resume_article.sql

application.properties :

spring.datasource.url=jdbc:mysql://localhost:3306/monblog
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=validate
spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration

Au démarrage, Spring Boot détecte Flyway, exécute les scripts non encore appliqués et valide le schéma avec Hibernate.

Test de mémorisation/compréhension


Quel est le préfixe obligatoire des fichiers de migration Flyway ?


Combien d'underscores séparent le numéro de version de la description dans le nom du fichier ?


Que se passe-t-il si vous modifiez un fichier de migration déjà exécuté en production ?


Quelle valeur de spring.jpa.hibernate.ddl-auto utiliser avec Flyway en production ?


Dans quel dossier placer les scripts de migration Flyway ?


Quelle table Flyway crée automatiquement pour suivre les migrations exécutées ?


TP pour réfléchir et résoudre des problèmes

Dans ce TP, vous allez mettre en place Flyway dans le projet MonBlog et créer les scripts de migration initiaux.

Étape 1 — Ajouter Flyway à pom.xml

Ajoutez les deux dépendances Flyway dans le pom.xml.


Bonne pratique - flyway-core et flyway-mysql ensemble

flyway-core contient le moteur de migration. flyway-mysql ajoute le support spécifique à MySQL (dialecte SQL, gestion des types). Les deux sont nécessaires pour un projet Spring Boot + MySQL.

Étape 2 — Configurer application.properties


Bonne pratique - validate en développement aussi

Même en développement, utilisez validate dès que Flyway est en place. Cela vous force à créer un script de migration pour chaque changement de schéma — ce qui documente l'évolution de votre base et prépare le terrain pour la production.

Étape 3 — Créer le script V1__init.sql

Créez le fichier src/main/resources/db/migration/V1__init.sql avec les tables articles et utilisateurs.


Bonne pratique - Scripts SQL idempotents

Utilisez CREATE TABLE IF NOT EXISTS pour rendre vos scripts plus robustes, même si Flyway ne les exécute normalement qu'une seule fois. Cela protège contre les exécutions manuelles accidentelles en dehors de Flyway.

📌 Une solution