Prisma sitzt beim Schema und beim Client. Daten sind der Teil, den es dir überlässt. Die offizielle Antwort heißt prisma db seed, und dieser Befehl führt schlicht eine TypeScript-Datei aus, die du selbst schreibst und von Hand aktuell hältst. In dieser Datei steckt der Schmerz.
Der Standard: ein seed.ts, das du von Hand pflegst
Du verdrahtest es in der package.json und schreibst das Skript:
// package.json
"prisma": { "seed": "tsx prisma/seed.ts" }
// prisma/seed.ts
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
const user = await prisma.user.create({
data: { email: "ada@example.com", name: "Ada" },
});
const post = await prisma.post.create({
data: { title: "Hallo", authorId: user.id },
});
await prisma.comment.create({
data: { body: "Schön", postId: post.id, authorId: user.id },
});
}
main().finally(() => prisma.$disconnect());
Für drei Zeilen ist das in Ordnung. Für eine realistische Datenbank wird daraus eine zweite Codebasis, und sie hat drei Schwachstellen, die nie verschwinden:
- Du sortierst die Inserts von Hand. User vor Post, Post vor Comment. Du sortierst dein eigenes Schema im Kopf topologisch, und eine falsche Reihenfolge ist ein Fremdschlüssel-Fehler zur Laufzeit.
- Es driftet vom Schema weg. Ergänze ein Pflichtfeld oder eine neue Beziehung in der
schema.prisma, und das Seed-Skript bricht, bis du jedencreate()-Aufruf nachziehst. - Die Verteilung ist gefälscht. Eine Schleife, die jedem User exakt fünf Posts gibt, sieht nicht aus wie Produktion. Der lange Schwanz, der eine User mit zweihundert Kommentaren, ist genau die Stelle, an der deine Pagination- und N+1-Bugs sitzen, und eine gleichförmige Schleife versteckt sie.
Die Lücke, die Snaplet hinterlässt
Der beliebte Notausgang war Snaplet: es las dein Schema und erzeugte Seed-Daten, du hast also kein Skript geschrieben. 2025 hat Snaplet sein Datenprodukt eingestellt. Das ließ viele Prisma-Teams auf einer aufgegebenen Abhängigkeit zurück, zurück beim handgeschriebenen seed.ts. Der Bedarf ist nicht weg, das Tool schon. (Den Umstiegs-Winkel haben wir unter SeedBase vs Snaplet Seed aufgeschrieben.)
Was du eigentlich willst
Die Seed-Daten sollten aus dem Schema fallen, das du ohnehin schon geschrieben hast. Gib einem Tool deine schema.prisma und bekomm eine Datenbank zurück, in der jede Beziehung auflöst, die Inserts eltern-zuerst herauskommen und die Form wie echtes Leben aussieht, ohne dass du irgendwas Zeile für Zeile beschreibst. Genau das macht SeedBase.
1. Auf dein Schema zeigen
SeedBase liest schema.prisma direkt, inklusive Models, Felder, Enums und @relation-Direktiven:
model User {
id Int @id @default(autoincrement())
email String @unique
name String
posts Post[]
comments Comment[]
}
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
comments Comment[]
}
model Comment {
id Int @id @default(autoincrement())
body String
post Post @relation(fields: [postId], references: [id])
postId Int
author User @relation(fields: [authorId], references: [id])
authorId Int
}
2. Generieren und die Daten ziehen
Leg aus dem Schema ein Projekt an, generiere, und zieh das Ergebnis als SQL (oder CSV / JSON). Jede authorId und postId zeigt auf eine real erzeugte Zeile, User kommen vor Posts, Posts vor Comments, es lädt also mit aktiven Constraints:
# den erzeugten Seed direkt in die Datenbank laden
psql "$DATABASE_URL" -f seedbase-<id>.sql
Aus dem VS-Code- oder JetBrains-Plugin ist es ein Schritt: der Connection-String wird automatisch aus dem datasource-Block deiner schema.prisma erkannt, und Load into Database (oder Reset & Reseed) führt es für dich aus, ohne den Editor zu verlassen.
3. prisma db seed behalten, wenn du magst
Du musst den Befehl nicht aufgeben. Lass dessen Skript auf die erzeugte SQL zeigen statt auf ein handgepflegtes seed.ts, dann läuft prisma db seed weiter, ist aber keine Datei mehr, die du bei jeder Schema-Änderung von Hand anfasst.
seed.ts völlig okay, behalt es. Das hier lohnt sich, wenn dein Schema relational ist und du eine realistische, populierte Datenbank willst, ohne ein Skript zu babysitten. SeedBase wurde gegen ein echtes 20-App-Projekt mit 226 Tabellen getestet, daher kommen die Beziehungs-Reihenfolge und das Verteilungs-Handling. EU-gehostet, keine Drittanbieter-Tracker, alles exportierbar, du steckst also nie so fest, wie es die Snaplet-Abschaltung allen beigebracht hat.
FAQ
Brauche ich noch eine prisma/seed.ts?
Nein. Du schreibst keine create()-Aufrufe mehr von Hand. Erzeuge einen Datensatz aus deinem Schema, zieh ihn als SQL und lade ihn, oder lade ihn direkt aus dem Editor-Plugin in deine Datenbank. Wenn du den Befehl prisma db seed magst, zeigt dessen Skript einfach auf die erzeugte SQL statt auf ein handgepflegtes seed.ts.
Liest SeedBase meine schema.prisma direkt?
Ja. Es parst schema.prisma, also Models, Felder, Enums und @relation-Direktiven, und erzeugt einen referenziell konsistenten Datensatz, bei dem Eltern-Zeilen vor den Kindern eingefügt werden. So lädt es mit aktiven Fremdschlüssel-Constraints.
Ist das ein Snaplet-Seed-Ersatz?
Es füllt dieselbe Lücke: Seed-Daten aus dem Schema erzeugen, statt ein Skript zu schreiben und zu pflegen. Snaplet hat sein Datenprodukt 2025 eingestellt. SeedBase wird gepflegt, ist EU-gehostet, und du kannst alles exportieren. Mehr unter SeedBase vs Snaplet Seed.
Sind die Seed-Daten für CI deterministisch?
Ja. Die Generierung ist geseedet, derselbe Seed erzeugt also dieselben Zeilen, und eine CI-Pipeline bekommt bei jedem Lauf einen stabilen, reproduzierbaren Datensatz.
Prisma aus dem Schema seeden, nicht aus einem Skript
Zeig SeedBase deine schema.prisma und erzeuge eine populierte, beziehungs-konsistente Datenbank mit realistischen Verteilungen. Kostenlose Stufe, keine Kreditkarte.
- Liest schema.prisma
- Jede Beziehung löst auf
- SQL / CSV / JSON
- EU-gehostet
Mehr: Prisma-Testdaten · vs Snaplet Seed · warum Faker bei FKs zerbricht