💻 Développement

dev-database-migration-helper

Gestion des migrations de bases de données et changements de schéma avec stratégies zero-downtime, rollback et data migration.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- dev-database-migration-helper --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } dev-database-migration-helper -Launch"

🚀 Déjà installé ?

claude "/dev-database-migration-helper"

Ou tapez /dev-database-migration-helper dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

migrationdatabase migrationchanger le schémaEF migrationsFlywayLiquibaseALTER TABLEzero downtime migration

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/dev-database-migration-helper ~/.claude/skills/

Payload du plugin : skills/dev-database-migration-helper · source éditable : dev-skills/database-migration-helper

📖 Manuel

Database Migration Helper

1. Qualifier le changement

Avant tout, caractériser l'opération :

TypeRisqueStratégie recommandée
Ajout colonne nullableFaibleMigration directe
Ajout colonne NOT NULL sans defaultÉlevéExpand-contract obligatoire
Renommage colonne/tableÉlevéAlias + expand-contract
Suppression colonne/tableÉlevéPhase contract après code nettoyé
Changement de typeÉlevéColonne intermédiaire + backfill
Ajout index (grande table)MoyenIndex CONCURRENTLY / online
Data migration (backfill)VariableBatches, jamais full-table en une passe

2. Choisir la stratégie

Expand-Contract (zero-downtime, recommandé pour prod)

Trois phases déployées séparément :

  1. Expand — ajouter la nouvelle colonne/table, sans toucher à l'ancienne.
  2. Migrate — double-écriture dans le code, backfill des données existantes.
  3. Contract — supprimer l'ancienne colonne/table une fois le code nettoyé déployé.

Migration avec fenêtre de maintenance

Acceptable uniquement si : trafic < 100 rps OU table < 100k lignes OU downtime explicitement accepté par le métier.

Blue-Green

Maintenir deux environnements avec bascule DNS/load-balancer. Adapté aux changements majeurs de schéma impossibles à rendre backward-compatible.


3. Écrire la migration selon l'outil

EF Core (C#)

dotnet ef migrations add AddUserEmailIndex --project src/Infrastructure
dotnet ef database update --connection "Server=...;Database=...;"
# Rollback vers migration précédente
dotnet ef database update NomMigrationPrecedente
// Migration générée — toujours vérifier le SQL produit
protected override void Up(MigrationBuilder mb)
{
    mb.AddColumn<string>("email_verified", "users", nullable: true);
    mb.CreateIndex("IX_users_email", "users", "email", unique: true);
}
protected override void Down(MigrationBuilder mb)
{
    mb.DropIndex("IX_users_email", "users");
    mb.DropColumn("email_verified", "users");
}

Flyway (SQL versionné)

db/migration/
  V1__create_users.sql
  V2__add_email_verified.sql
  V20260624_001__backfill_email.sql   # préfixe date pour éviter conflits
flyway -url=jdbc:postgresql://host/db -user=x -password=y migrate
flyway info        # état des migrations
flyway repair      # si checksum corrompu

Liquibase

# changelog-v3.yaml
databaseChangeLog:
  - changeSet:
      id: add-email-verified
      author: k.benazzouz
      changes:
        - addColumn:
            tableName: users
            columns:
              - column:
                  name: email_verified
                  type: boolean
                  defaultValueBoolean: false
      rollback:
        - dropColumn:
            tableName: users
            columnName: email_verified

Alembic (Python)

alembic revision --autogenerate -m "add_email_verified"
alembic upgrade head
alembic downgrade -1   # rollback d'une révision

SQL brut versionné

Nommage : V<YYYYMMDD>_<NNN>__<description>.sql + script rollback/R<YYYYMMDD>_<NNN>__<description>.sql obligatoire.


4. Backfill de données existantes (batches)

Ne jamais backfiller une grande table en une seule transaction — risque de lock prolongé et timeout.

-- PostgreSQL / SQL Server : backfill par batch de 10 000 lignes
DO $$
DECLARE
  last_id BIGINT := 0;
  batch   BIGINT := 10000;
BEGIN
  LOOP
    UPDATE users
    SET email_verified = false
    WHERE id > last_id AND id <= last_id + batch
      AND email_verified IS NULL;
    EXIT WHEN NOT FOUND;
    last_id := last_id + batch;
    PERFORM pg_sleep(0.1);  -- respiration entre batches
  END LOOP;
END $$;
-- SQL Server : même principe avec TOP
DECLARE @batch INT = 10000;
WHILE 1=1
BEGIN
  UPDATE TOP (@batch) users
  SET email_verified = 0
  WHERE email_verified IS NULL;
  IF @@ROWCOUNT = 0 BREAK;
  WAITFOR DELAY '00:00:00.100';
END

5. Grandes tables — opérations online

PostgreSQL

-- Index sans lock table (peut prendre du temps, c'est voulu)
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
-- Contrainte NOT NULL sans réécriture complète (PG 12+)
ALTER TABLE users ALTER COLUMN email SET NOT NULL; -- rapide si CHECK déjà validé
ALTER TABLE users ADD CONSTRAINT chk_email_notnull CHECK (email IS NOT NULL) NOT VALID;
ALTER TABLE users VALIDATE CONSTRAINT chk_email_notnull; -- scan en arrière-plan

MySQL

# pt-online-schema-change (Percona Toolkit) — pas de lock table
pt-online-schema-change --alter "ADD COLUMN email_verified TINYINT(1) DEFAULT 0" \
  D=mydb,t=users --execute
# gh-ost (GitHub) — alternative sans triggers
gh-ost --database mydb --table users \
  --alter "ADD COLUMN email_verified TINYINT(1) DEFAULT 0" \
  --execute

6. Tester avant production

# Dump anonymisé de prod vers staging
pg_dump prod_db | psql staging_db
# Mesurer la durée réelle
\timing on   -- psql
# Détecter les locks
-- PostgreSQL
SELECT pid, query, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event IS NOT NULL;
-- SQL Server
SELECT * FROM sys.dm_exec_requests WHERE blocking_session_id <> 0;
# Valider le plan post-migration
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM users WHERE email = 'test@test.com';

Checklist staging :


7. Rollback strategy


8. Garde-fous et anti-patterns

Ne jamais faire :

Toujours faire :