Back

Schema-First Datenbankentwicklung mit Drizzle

Schema-First Datenbankentwicklung mit Drizzle

Ihre TypeScript-Typen sagen das eine. Ihre Datenbank sagt etwas anderes. Abfragen schlagen zur Laufzeit fehl, und Sie debuggen Inkonsistenzen, die nie hätten existieren dürfen.

Schema-First Datenbankdesign mit Drizzle löst dieses Problem, indem es Ihren TypeScript-Code zur einzigen Quelle der Wahrheit macht. Ihre Schema-Definitionen steuern sowohl Ihre Anwendungstypen als auch Ihre Datenbankstruktur und eliminieren die Diskrepanz, die zu Laufzeit-Überraschungen führt.

Dieser Artikel erklärt, wie die Schema-First-Entwicklung mit Drizzle ORM funktioniert, wann Sie verschiedene Migrations-Workflows verwenden sollten und welche häufigen Fallstricke Sie vermeiden sollten.

Wichtigste Erkenntnisse

  • Drizzle ORM folgt einem Code-First-Ansatz, bei dem TypeScript-Schema-Definitionen als einzige Quelle der Wahrheit für Typen, Abfragen und Datenbankstruktur dienen.
  • Drizzle Kit bietet zwei Migrationspfade: push für schnelle lokale Iteration und generate/migrate für nachvollziehbare, teamsichere Deployments.
  • Für Brownfield-Projekte mit bestehenden Datenbanken verwenden Sie drizzle-kit pull, um Ihr Schema zu introspektieren, bevor Sie Migrationen generieren, um das Neuerstellen von Tabellen zu vermeiden.
  • Inkonsistenzen bei Constraint-Namen zwischen Drizzles deterministischer Benennung und manuell erstellten Datenbanken können unerwartete Migrations-Anweisungen auslösen.

Was Schema-First bei Drizzle tatsächlich bedeutet

Drizzle ist grundlegend Code-First. Sie definieren Tabellen, Spalten und Beziehungen in TypeScript, und diese Definition wird maßgeblich für alles Nachfolgende – Abfragen, Migrationen und Typinferenz.

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(),
})

Diese Schema-Datei erfüllt zwei Zwecke. Drizzle ORM verwendet sie für typsichere Abfragen. Drizzle Kit verwendet sie, um Datenbankänderungen zu generieren oder anzuwenden.

Der Begriff „Schema-First” bedeutet hier, dass Ihre TypeScript-Definitionen führen. Die Datenbank folgt.

Code-First vs. Database-First: Die Unterscheidung verstehen

Traditionelle Database-First-Workflows behandeln die Datenbank als maßgeblich. Sie erstellen Tabellen manuell oder mit SQL-Skripten und generieren dann Anwendungscode aus der bestehenden Struktur.

Code-First- und Database-First-Vergleiche vermischen diese Begriffe oft. Im Kontext von Drizzle:

  • Code-First: Ihr TypeScript-Schema steuert Datenbankänderungen
  • Database-First: Sie ziehen die bestehende Datenbankstruktur mit drizzle-kit pull in TypeScript

Drizzle unterstützt beides. Für Greenfield-Projekte ist Code-First typischerweise sauberer. Für Brownfield-Szenarien – wenn Sie zu einem Projekt mit bestehender Datenbank hinzustoßen – bringt Sie die Introspektion via pull schnell zum Ziel.

Der Drizzle Kit Workflow: Push vs. Generate

Drizzle Kit bietet zwei primäre Wege, um Schema-Änderungen auf Ihre Datenbank anzuwenden.

Schema Push für schnelle Iteration

npx drizzle-kit push

Push vergleicht Ihr Schema mit der Datenbank und wendet Änderungen direkt an. Keine Migrationsdateien. Kein Review-Schritt.

Dies funktioniert gut für:

  • Solo-Projekte
  • Frühes Prototyping
  • Lokale Entwicklungsdatenbanken, die Sie neu erstellen können

Der Kompromiss ist die Sichtbarkeit. Sie haben keine Aufzeichnung darüber, was sich wann geändert hat.

Generierte Migrationen für Team-Sicherheit

npx drizzle-kit generate
npx drizzle-kit migrate

generate erstellt SQL-Migrationsdateien. migrate wendet sie an. Die Dateien leben in der Versionskontrolle und schaffen einen Audit-Trail.

Dieser Ansatz eignet sich für:

  • Team-Umgebungen, in denen Änderungen überprüft werden müssen
  • Produktions-Deployments, die Rollback-Fähigkeit erfordern
  • Compliance-Szenarien, die Änderungsdokumentation benötigen

Keine Methode ist universell richtig. Der Drizzle Kit Workflow berücksichtigt beide je nach Ihrem Kontext.

Drizzle Kit konfigurieren

Ihre drizzle.config.ts teilt Drizzle Kit mit, wo Schemas zu finden sind und Migrationen gespeichert werden:

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 unterstützt wichtige SQL-Datenbanken einschließlich PostgreSQL, MySQL und SQLite/libSQL, mit zusätzlichen Dialekten wie MSSQL und CockroachDB, die hinzukommen. Die Konfiguration bleibt über Datenbanken hinweg weitgehend konsistent – nur der Dialekt und treiberspezifische Optionen ändern sich.

Häufige Fallstricke, die Sie vermeiden sollten

Schema-First-Entwicklung mit Drizzle ist nicht ohne Reibungspunkte.

Bestehende Tabellen erfordern sorgfältige Handhabung. Wenn Sie Drizzle auf einer Datenbank mit bestehenden Tabellen einführen, könnte Ihr erstes generate Migrationen erzeugen, die versuchen, alles neu zu erstellen. Verwenden Sie zuerst pull, um Ihre Schema-Datei mit der Realität zu synchronisieren.

Introspektion kann verrauschte Diffs erzeugen. Das Pullen aus einer Datenbank kann Constraint-Namen oder Defaults enthalten, die sich von dem unterscheiden, was Sie manuell schreiben würden. Nachfolgende Generates können diese als Änderungen markieren, auch wenn sich nichts Bedeutsames geändert hat.

Inkonsistenzen bei Constraint-Namen verursachen unerwartete Migrationen. Drizzle generiert Constraint-Namen deterministisch. Wenn Ihre Datenbank andere Namen hat (durch manuelle Erstellung oder ein anderes Tool), sehen Sie ALTER-Anweisungen, die Constraints umbenennen, ohne das Verhalten zu ändern.

Laufzeit-Migrationen benötigen Fehlerbehandlung. Wenn Sie Migrationen programmatisch während des Deployments anwenden, umschließen Sie diese mit ordentlicher Fehlerbehandlung. Eine fehlgeschlagene Migration mitten im Deployment kann Ihre Datenbank in einem inkonsistenten Zustand hinterlassen.

Wann Schema-First Ihren Workflow verbessert

Drizzle ORM Schema-First-Entwicklung glänzt, wenn:

  • Sie Compile-Time-Garantien wollen, dass Abfragen zu Ihrem Schema passen
  • Mehrere Entwickler Datenbankänderungen koordinieren müssen
  • Sie in Edge- oder Serverless-Umgebungen deployen, wo die Bundle-Größe wichtig ist
  • Sie SQL-ähnliche Syntax gegenüber abstrahierten Query-Buildern bevorzugen

Drizzle Studio ergänzt diesen Workflow mit einer visuellen Oberfläche zum Durchsuchen von Daten und Testen von Abfragen gegen Ihr Schema.

Fazit

Beginnen Sie mit Ihrer Schema-Datei. Definieren Sie Tabellen, die zu Ihrer Domäne passen. Verwenden Sie push während der lokalen Iteration und wechseln Sie dann zu generate und migrate, bevor Sie Teammitglieder einbeziehen oder in Produktion deployen.

Das Ziel ist nicht, einen Workflow für immer zu wählen – es geht darum, die Kompromisse zu verstehen, damit Sie das richtige Werkzeug für jede Entwicklungsphase wählen.

FAQs

Ja. Führen Sie drizzle-kit pull aus, um Ihre bestehende Datenbank zu introspektieren und ein passendes TypeScript-Schema zu generieren. Dies vermeidet destruktive Migrationen. Sobald Ihre Schema-Datei den aktuellen Datenbankzustand widerspiegelt, können Sie generate und migrate für alle zukünftigen Änderungen verwenden, ohne Datenverlust zu riskieren.

Wechseln Sie zu generate, sobald Ihr Projekt über Solo-Prototyping hinausgeht. Sobald andere Entwickler beteiligt sind oder Sie in Staging oder Produktion deployen, bieten Migrationsdateien den Audit-Trail und Review-Prozess, den Sie benötigen. Push ist am besten für die lokale Entwicklung reserviert, wo die Datenbank sicher neu erstellt werden kann.

Ja. Drizzle unterstützt die Definition von Foreign Keys direkt in Ihrem Schema und bietet eine Relations-API zur Deklaration von One-to-One-, One-to-Many- und Many-to-Many-Beziehungen. Diese Beziehungen treiben die relationale Query-API an, die es Ihnen ermöglicht, verschachtelte Daten typsicher abzurufen, ohne rohe SQL-Joins zu schreiben.

Beide sind Code-First-ORMs, unterscheiden sich aber in der Philosophie. Prisma verwendet eine eigene Schema-Sprache und generiert daraus einen Client. Drizzle definiert Schemas in reinem TypeScript und gibt Ihnen direkte Kontrolle über die SQL-Ausgabe und kleinere Bundle-Größen. Drizzle ist von Design her näher an SQL, während Prisma mehr davon abstrahiert.

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.

OpenReplay