Développement de base de données Schema-First avec Drizzle
Vos types TypeScript disent une chose. Votre base de données en dit une autre. Les requêtes échouent à l’exécution, et vous vous retrouvez à déboguer des incohérences qui n’auraient jamais dû exister.
La conception de base de données schema-first avec Drizzle résout ce problème en faisant de votre code TypeScript la source de vérité unique. Vos définitions de schéma pilotent à la fois vos types d’application et votre structure de base de données, éliminant ainsi la déconnexion qui cause des surprises à l’exécution.
Cet article explique comment fonctionne le développement schema-first avec Drizzle ORM, quand utiliser différents workflows de migration, et les pièges courants à éviter.
Points clés à retenir
- Drizzle ORM suit une approche code-first où les définitions de schéma TypeScript servent de source de vérité unique pour les types, les requêtes et la structure de base de données.
- Drizzle Kit offre deux chemins de migration :
pushpour une itération locale rapide etgenerate/migratepour des déploiements auditables et sécurisés en équipe. - Pour les projets brownfield avec des bases de données existantes, utilisez
drizzle-kit pullpour introspecter votre schéma avant de générer des migrations afin d’éviter de recréer les tables. - Les incohérences de noms de contraintes entre le nommage déterministe de Drizzle et les bases de données créées manuellement peuvent déclencher des instructions de migration inattendues.
Ce que signifie réellement Schema-First dans Drizzle
Drizzle est fondamentalement code-first. Vous définissez les tables, colonnes et relations en TypeScript, et cette définition devient autoritaire pour tout ce qui suit en aval—requêtes, migrations et inférence de types.
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core"
export const posts = pgTable("posts", {
id: serial().primaryKey(),
title: text().notNull(),
content: text(),
createdAt: timestamp().defaultNow(),
})
Ce fichier de schéma a une double fonction. Drizzle ORM l’utilise pour des requêtes type-safe. Drizzle Kit l’utilise pour générer ou appliquer des modifications de base de données.
Le terme « schema-first » signifie ici que vos définitions TypeScript mènent la danse. La base de données suit.
Code-First vs Database-First : comprendre la distinction
Les workflows traditionnels database-first traitent la base de données comme autoritaire. Vous créez les tables manuellement ou avec des scripts SQL, puis générez le code applicatif à partir de la structure existante.
Les comparaisons entre code-first et database-first confondent souvent ces termes. Dans le contexte de Drizzle :
- Code-first : votre schéma TypeScript pilote les modifications de base de données
- Database-first : vous récupérez la structure de base de données existante dans TypeScript en utilisant
drizzle-kit pull
Drizzle supporte les deux. Pour les projets greenfield, le code-first est généralement plus propre. Pour les scénarios brownfield—rejoindre un projet avec une base de données existante—l’introspection via pull vous permet de démarrer rapidement.
Le workflow Drizzle Kit : Push vs Generate
Drizzle Kit offre deux chemins principaux pour appliquer les modifications de schéma à votre base de données.
Schema Push pour une itération rapide
npx drizzle-kit push
Push compare votre schéma à la base de données et applique les modifications directement. Pas de fichiers de migration. Pas d’étape de révision.
Cela fonctionne bien pour :
- Les projets solo
- Le prototypage précoce
- Les bases de données de développement local que vous pouvez recréer
Le compromis est la visibilité. Vous n’aurez pas d’enregistrement de ce qui a changé ou quand.
Migrations générées pour la sécurité en équipe
npx drizzle-kit generate
npx drizzle-kit migrate
generate crée des fichiers de migration SQL. migrate les applique. Les fichiers vivent dans le contrôle de version, créant une piste d’audit.
Cette approche convient pour :
- Les environnements d’équipe où les modifications nécessitent une révision
- Les déploiements en production nécessitant une capacité de rollback
- Les scénarios de conformité nécessitant une documentation des modifications
Aucune méthode n’est universellement correcte. Le workflow Drizzle Kit s’adapte aux deux selon votre contexte.
Discover how at OpenReplay.com.
Configuration de Drizzle Kit
Votre drizzle.config.ts indique à Drizzle Kit où trouver les schémas et stocker les migrations :
import { defineConfig } from "drizzle-kit"
export default defineConfig({
dialect: "postgresql",
schema: "./src/db/schema.ts",
out: "./drizzle/migrations",
dbCredentials: {
url: process.env.DATABASE_URL!,
},
})
Drizzle supporte les principales bases de données SQL, notamment PostgreSQL, MySQL et SQLite/libSQL, avec des dialectes supplémentaires tels que MSSQL et CockroachDB en développement. La configuration reste largement cohérente entre les bases de données—seuls le dialecte et les options spécifiques au pilote changent.
Pièges courants à éviter
Le développement schema-first avec Drizzle n’est pas sans points de friction.
Les tables existantes nécessitent une manipulation prudente. Si vous adoptez Drizzle sur une base de données avec des tables existantes, votre premier generate peut produire des migrations qui tentent de tout recréer. Utilisez d’abord pull pour synchroniser votre fichier de schéma avec la réalité.
L’introspection peut produire des différences bruyantes. Récupérer depuis une base de données peut inclure des noms de contraintes ou des valeurs par défaut qui diffèrent de ce que vous écririez manuellement. Les générations suivantes peuvent signaler ces éléments comme des modifications même si rien de significatif n’a changé.
Les incohérences de noms de contraintes causent des migrations inattendues. Drizzle génère les noms de contraintes de manière déterministe. Si votre base de données a des noms différents (issus d’une création manuelle ou d’un autre outil), vous verrez des instructions ALTER qui renomment les contraintes sans changer le comportement.
Les migrations à l’exécution nécessitent une gestion des erreurs. Si vous appliquez des migrations par programmation pendant le déploiement, enveloppez-les dans une gestion d’erreurs appropriée. Une migration échouée en cours de déploiement peut laisser votre base de données dans un état incohérent.
Quand Schema-First améliore votre workflow
Le développement schema-first avec Drizzle ORM brille lorsque :
- Vous voulez des garanties à la compilation que les requêtes correspondent à votre schéma
- Plusieurs développeurs doivent coordonner les modifications de base de données
- Vous déployez vers des environnements edge ou serverless où la taille du bundle compte
- Vous préférez une syntaxe proche de SQL plutôt que des query builders abstraits
Drizzle Studio complète ce workflow avec une interface visuelle pour parcourir les données et tester les requêtes contre votre schéma.
Conclusion
Commencez par votre fichier de schéma. Définissez des tables qui correspondent à votre domaine. Utilisez push pendant l’itération locale, puis passez à generate et migrate avant d’impliquer des coéquipiers ou de déployer en production.
L’objectif n’est pas de choisir un workflow pour toujours—c’est de comprendre les compromis pour choisir le bon outil pour chaque phase de développement.
FAQ
Oui. Exécutez drizzle-kit pull pour introspecter votre base de données existante et générer un schéma TypeScript correspondant. Cela évite les migrations destructrices. Une fois que votre fichier de schéma reflète l'état actuel de la base de données, vous pouvez commencer à utiliser generate et migrate pour toutes les modifications futures sans risquer de perte de données.
Passez à generate une fois que votre projet dépasse le stade du prototypage solo. Dès que d'autres développeurs sont impliqués ou que vous déployez en staging ou production, les fichiers de migration fournissent la piste d'audit et le processus de révision dont vous avez besoin. Push est mieux réservé au développement local où la base de données peut être recréée en toute sécurité.
Oui. Drizzle supporte la définition de clés étrangères directement dans votre schéma et fournit une API de relations pour déclarer des relations one-to-one, one-to-many et many-to-many. Ces relations alimentent l'API de requêtes relationnelles, qui vous permet de récupérer des données imbriquées de manière type-safe sans écrire de jointures SQL brutes.
Les deux sont des ORM code-first, mais ils diffèrent dans leur philosophie. Prisma utilise son propre langage de schéma et génère un client à partir de celui-ci. Drizzle définit les schémas en TypeScript pur, vous donnant un contrôle direct sur la sortie SQL et des tailles de bundle plus petites. Drizzle est plus proche de SQL par conception, tandis que Prisma en abstrait davantage.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.