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
- Editer
backend/src/db/schema.tspour ajouter/retirer/modifier tables ou enums. - Lancer
npx drizzle-kit generatepour créer une migration et mettre à jour le snapshot. - Revoir les fichiers SQL générés dans
backend/drizzle. - Tester localement en appliquant la migration sur une base de développement :
npx drizzle-kit migrate. - 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 dedrizzle-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 dedrizzle-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)etinsertMultipleAndReturnId(table, values).select(table, where?): sélectionne les lignes en filtrant automatiquement les soft-deleted (colonnesdeletedAt).update(table, set, where): met à jour et met à jourupdatedAt.delete(table, where?): soft-delete (setdeletedAt).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.)