Aller au contenu
Nibiru docsv0.9.2

Migrations

Migrations numérotées basées sur le CLI Nibiru.

Stable Reading time ~ 3 min Edit on GitHub

Les migrations sont des fichiers SQL simples situés dans application/settings/config/database/, exécutés dans un ordre numérique. L’interface de ligne de commande (CLI) suit les fichiers qui ont été exécutés et les ignore lors des appels ultérieurs.

NNN-<slug>.sql
  • NNN : numéro à zéro pad de trois chiffres pour l’ordre de tri.
  • <slug> : description en kebab-case (ajouter-compte-e-mail, créer-données-acl).

Exemple de progression :

001-acl.sql
002-account.sql
003-api_registry.sql
004-timeanddate.sql
005-user.sql
006-user_to_account.sql
007-timeanddate_to_account.sql
008-user_to_acl.sql
009-account_to_api_registry.sql
010-timeanddate_to_user.sql
011-acl-data.sql
012-add-unique-key-user.sql
013-add-account-email.sql
Fenêtre de terminal
./nibiru -mi local # APPLICATION_ENV=development
APPLICATION_ENV=staging ./nibiru -mi staging
APPLICATION_ENV=production ./nibiru -mi production

L’argument {env} et APPLICATION_ENV doivent concorder. Les migrations ciblent la base de données configurée dans settings.<env>.ini sous [DATABASE].

Pour chaque fichier *.sql dans l’ordre numérique :

  1. Recherche son nom de fichier dans la table _migrations.
  2. S’il est absent, ouvre une transaction (si le pilote prend en charge les transactions DDL), exécute le fichier et insère un enregistrement en cas de succès.
  3. Si une instruction échoue, annule et quitte avec un code non nul.

La table _migrations est créée automatiquement lors du premier démarrage.

Toujours écrire des migrations qui peuvent être relancées sans erreurs après un échec partiel :

CREATE TABLE IF NOT EXISTS api_registry (
api_registry_id INT(11) NOT NULL AUTO_INCREMENT,
api_registry_name VARCHAR(255) NOT NULL,
PRIMARY KEY (api_registry_id),
UNIQUE KEY api_registry_name_uk (api_registry_name)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;

Pour PostgreSQL :

CREATE TABLE IF NOT EXISTS api_registry (
api_registry_id SERIAL PRIMARY KEY,
api_registry_name TEXT NOT NULL UNIQUE
);

Pour les instructions ALTER, privilégiez les clauses IF NOT EXISTS sur les moteurs pris en charge :

ALTER TABLE "user" ADD COLUMN IF NOT EXISTS user_email VARCHAR(255);

Si votre moteur ne prend pas en charge IF NOT EXISTS lors de l’alteration, enveloppez l’instruction dans une requête de garde qui n’exécute aucune action lorsque le changement existe déjà.

Fenêtre de terminal
./nibiru -mi-reset local # forget all applied migrations
./nibiru -mi-reset-file 005-user.sql local # forget a single file

Le formulaire à un seul fichier est utile lorsque vous avez corrigé un bogue dans une migration précédemment appliquée et que vous souhaitez relancer uniquement ce fichier.

Deux ingénieurs travaillant sur des branches parallèles peuvent tous deux ajouter 015-… et entrer en collision. Les conventions qui aident :

  • Reservez des numéros dans les titres de pull-request avant d’écrire le SQL.
  • Utilisez un écart généreux pour les hotfixes (par exemple, réservez 099, 199, 299 pour les cherry-picks d’urgence).
  • Privilégiez les migrations additives (nouvelles tables, nouvelles colonnes) plutôt que les destructives (drops). Elles fusionnent plus proprement.

Pour les projets à long terme, procédez périodiquement à la consolidation des anciennes migrations dans un seul fichier seed représentant le schéma actuel. Déplacez les originaux vers archive/ pour que l’historique d’audit reste intact, et créez un nouveau 000-baseline-2026.sql qui crée tout à la fois. Mettez à jour le lanceur de migrations avec une insertion manuelle dans _migrations pour marquer les anciens fichiers comme appliqués.

Lorsque [GENERATOR] database = true, les modèles sont régénérés à partir du schéma en direct après chaque migration. Ainsi, un déploiement typique est le suivant :

Fenêtre de terminal
./nibiru -mi production
# Generator regenerates models on the next request.
./nibiru -cache-clear

Pour les déploiements sans interruption : éteignez le générateur (database = false) et enregistrez les modèles régénérés avec les migrations dont ils dépendent.