Prisma ORM mit Claude Code: TypeScript-Datenbankzugriff 2026

Prisma ist das modernste ORM für Node.js und TypeScript — vollständige Typ-Sicherheit, Auto-Completion, einfache Migrations. Claude Code kennt Prisma in- und auswendig: Schema-Design, komplexe Queries, Performance-Optimierung und sichere Migrations.

Prisma Setup und Schema-Design

SchemaDatenmodell mit Claude Code entwerfen

# Prompt: "Entwirf Prisma-Schema für eine SaaS-App mit: # Users, Organizations (Multi-Tenancy), Projects, Tags (M:N) # Soft-Delete für alle Hauptentitäten" # schema.prisma — Claude Code generiert: generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique name String? createdAt DateTime @default(now()) deletedAt DateTime? // Soft Delete memberships OrgMembership[] @@index([email]) @@map("users") } model Organization { id String @id @default(cuid()) name String slug String @unique plan Plan @default(FREE) createdAt DateTime @default(now()) deletedAt DateTime? members OrgMembership[] projects Project[] @@map("organizations") } model OrgMembership { userId String orgId String role Role @default(MEMBER) user User @relation(fields: [userId], references: [id]) org Organization @relation(fields: [orgId], references: [id]) @@id([userId, orgId]) // Composite PK } model Project { id String @id @default(cuid()) name String orgId String createdAt DateTime @default(now()) deletedAt DateTime? org Organization @relation(fields: [orgId], references: [id]) tags ProjectTag[] @@index([orgId, deletedAt]) } // Many-to-Many via explizite Zwischentabelle model Tag { id String @id @default(cuid()) name String projects ProjectTag[] } model ProjectTag { projectId String tagId String project Project @relation(fields: [projectId], references: [id]) tag Tag @relation(fields: [tagId], references: [id]) @@id([projectId, tagId]) } enum Plan { FREE PRO ENTERPRISE } enum Role { OWNER ADMIN MEMBER }

Migrations: Sicher in Production

MigrationWorkflow für Production-Migrations

# Development: Migration erstellen npx prisma migrate dev --name add_user_avatar # Production: Migration anwenden (KEIN migrate dev!) npx prisma migrate deploy # Schema-Änderungen die Claude Code sicher generiert: # ✅ Neue Tabelle hinzufügen # ✅ Nullable Spalte hinzufügen # ✅ Index hinzufügen (mit CONCURRENTLY-Hinweis) # ⚠️ NOT NULL Spalte auf bestehender Tabelle → Backfill nötig! # ⚠️ Spalte umbenennen → Daten-Verlust-Risiko → Claude warnt! # NOT NULL ohne Downtime — 3-Schritt-Migration: # 1. Spalte als nullable hinzufügen # 2. Backfill: UPDATE users SET avatar_url = '' WHERE avatar_url IS NULL # 3. NOT NULL Constraint hinzufügen (separate Migration)
Production-Migration Regel: Niemals prisma migrate dev in Production. Immer prisma migrate deploy. Claude Code kennt diesen Unterschied und warnt aktiv — nutze es.

Queries: Von einfach bis komplex

QueriesRelations, Filtering, Aggregation

# Prompt: "Lade alle aktiven Projects einer Org mit Tags und Member-Count" const projects = await prisma.project.findMany({ where: { orgId, deletedAt: null, // Soft-Delete Filter name: { contains: search, mode: 'insensitive' } }, include: { tags: { include: { tag: true } // M:N via Zwischentabelle }, _count: { select: { members: true } // Aggregate ohne extra Query } }, orderBy: { createdAt: 'desc' }, take: 20, skip: (page - 1) * 20 // Pagination }); # Upsert: Create oder Update in einem Call await prisma.orgMembership.upsert({ where: { userId_orgId: { userId, orgId } }, create: { userId, orgId, role: 'MEMBER' }, update: { role: 'ADMIN' } }); # Raw Query wenn Prisma nicht ausreicht: const result = await prisma.$queryRaw` SELECT org_id, COUNT(*) as project_count FROM projects WHERE deleted_at IS NULL GROUP BY org_id HAVING COUNT(*) > 10 `;

Transactions: Atomare Operationen

# Prompt: "Erstelle einen User und seine Default-Organization atomar" async function createUserWithOrg(email, name, orgName) { return prisma.$transaction(async (tx) => { // tx = transaktionaler Prisma-Client const user = await tx.user.create({ data: { email, name } }); const org = await tx.organization.create({ data: { name: orgName, slug: slugify(orgName) + '-' + nanoid(4), members: { create: { userId: user.id, role: 'OWNER' } } } }); return { user, org }; }); // Bei Fehler: automatischer Rollback! }

Performance-Optimierung

PerformanceN+1-Problem und Query-Optimierung

# N+1 Problem — Claude Code erkennt und fixt: # SCHLECHT: Eine Query pro Project für Tags for (const project of projects) { project.tags = await prisma.projectTag.findMany({ where: { projectId: project.id } }); } # 100 Projects = 101 Queries! # GUT: Alles in einer Query mit include const projects = await prisma.project.findMany({ include: { tags: { include: { tag: true } } } }); # 1 Query — Prisma batcht automatisch # Connection Pool für Production (nicht Standard!): # DATABASE_URL="postgresql://...?connection_limit=10&pool_timeout=20" # Oder: Prisma Accelerate für globales Connection Pooling # Query-Logging für Performance-Analyse: const prisma = new PrismaClient({ log: ['query', 'slow_query'], // slow_query: Queries > 1000ms loggen });
Prisma Prompt-Tipp: "Analysiere diese Prisma-Queries auf N+1-Probleme und fehlende Indizes. Zeige die optimierte Version." Claude Code erkennt typische Muster und schlägt include-basierte Lösungen vor.

Datenbank-Modul im Kurs

Im Claude Code Mastery Kurs: vollständiges Prisma-Modul mit Schema-Design, Production-Migrations, komplexen Relations, Transactions und Performance-Optimierung — inkl. N+1-Problem-Erkennung und Query-Analyse.

14 Tage kostenlos testen →