Aller au contenu principal

Migrations & Drizzle

Commandes utiles (drizzle-kit)

Les commandes utilisées dans ce projet reposent sur npx drizzle-kit. Pour l'utiliser, vous devrez peut-être faire un npm install.

Générer les fichiers de migration / snapshot à partir du schéma TypeScript :

cd backend
npx drizzle-kit generate

Cette commande lit schema (backend/src/db/schema.ts) et écrit les SQL et snapshot(s) dans le dossier configuré out (backend/drizzle).

Appliquer les migrations sur la base (run migrations) :

cd backend
npx drizzle-kit migrate

Workflow recommandé pour modifier le schéma

  1. Editer backend/src/db/schema.ts pour ajouter/retirer/modifier tables ou enums.
  2. Lancer npx drizzle-kit generate pour créer une migration et mettre à jour le snapshot.
  3. Revoir les fichiers SQL générés dans backend/drizzle.
  4. Tester localement en appliquant la migration sur une base de développement : npx drizzle-kit migrate.
  5. Committer les fichiers SQL et le snapshot dans le repo.

L'image docker du backend se charge d'effectuer les migrations lors des déploiements, tant que ces migrations sont bien présentes dans le repo.

Comment gérer les MR/git-merge avec des migrations ?

Si vous voulez ajouter des migrations, lorsque vous faites vos MR sur dev, assurez-vous que vos migrations ne rentrent pas en conflit avec d'autres migrations qui ont été rajoutées entre-temps. Si besoin, on vous conseille de réconcilier vos changements de schéma sur votre branche en local avec ceux de la branche dev:

cd backend/
git merge dev
# accepter les changements de la branche `dev` sur les fichiers `_journal.json`, `00xx_snapshot.json`
# supprimer les fichiers de migration qui ne sont présents que sur notre branche (les migrations, ainsi que les snapshots supplémentaires)
npx drizzle-kit generate
# si besoin, git add, git commit, git push...

Cette problématique s'applique également aux MRs en preprod.

Fichiers clés

  • backend/drizzle.config.ts : configuration de drizzle-kit (schema, out, dialect, dbCredentials).
  • backend/src/db/schema.ts : définition des tables et enums (ex : usersTable, foodTable, foodCategoryEnum).
  • backend/src/db/drizzle.service.ts : wrapper NestJS autour de drizzle-orm (méthodes utilitaires pour select/insert/update/delete).
  • backend/drizzle/XXXX_*.sql : migrations qui seront exécutées sur les bases de données.
  • backend/drizzle/meta/_journal.json : fichier précisant quelles migrations doivent être faites dans quel ordre.
  • backend/drizzle/meta/XXXX_snapshot.json : snapshots de migrations, servant à drizzle pour savoir l'état de la BDD après chaque migration.

Variables d'environnement importantes

  • DATABASE_URL : URL de connexion PostgreSQL (ex: postgres://user:pwd@localhost:5432/db).

Utiliser DrizzleService dans le code NestJS

Le projet expose un DrizzleService prêt à l'emploi. Il fournit des méthodes utiles et standardisées :

  • insert(table, value) : insère une ligne.
  • insertAndReturnId(table, value) : insère et retourne l'id (utile pour relations).
  • insertMultiple(table, values) et insertMultipleAndReturnId(table, values).
  • select(table, where?) : sélectionne les lignes en filtrant automatiquement les soft-deleted (colonnes deletedAt).
  • update(table, set, where) : met à jour et met à jour updatedAt.
  • delete(table, where?) : soft-delete (set deletedAt).
  • unDelete(table, where?) : annule le soft-delete.
  • getRawHandle() : accès direct au client Drizzle (NodePgDatabase) si besoin. Vous ne devriez pas avoir besoin de ça, sauf si vous faites des opérations très spécifiques sur votre db.

Exemple rapide d'usage dans un service NestJS :

// ... dans un service NestJS
constructor(private readonly drizzle: DrizzleService) {}

async createFood(payload: { name: string; description: string; category: any; price?: number }) {
const id = await this.drizzle.insertAndReturnId(foodTable, payload);
return { id };
}

async listFoods() {
return this.drizzle.select(foodTable);
}

(Remplacer foodTable par l'import depuis backend/src/db/schema.)