DB Seed Generator
Before generating any output, read config/defaults.md and adapt all patterns, imports, and code examples to the user's configured stack.
Process
- Read
schema.prisma and extract all models, fields, types, constraints, relations, and enums.
- Determine dependency order: models with no required relations first, then models that depend on them.
- Generate a
prisma/seed.ts file with realistic fake data that respects all constraints.
- Output a ready-to-run seed file.
Dependency Ordering
Build a directed graph of model dependencies from @relation fields. Topologically sort so parent records are created before children.
User (no deps) → create first
Organization (no deps) → create first
Post (depends on User) → create second
Comment (depends on User, Post) → create third
If circular dependencies exist, use a two-pass approach: create records with required fields first, then update with optional relation fields.
Data Generation Rules
Field Name Conventions
Generate realistic values based on field names:
| Pattern |
Generated value |
firstName |
"Elena", "Marcus", "Priya" |
lastName |
"Rodriguez", "Chen", "Okafor" |
name (on User) |
"Elena Rodriguez" |
email |
"elena.rodriguez@example.com" |
phone |
"555-0101", "555-0102" |
avatarUrl, imageUrl |
"https://example.com/avatars/1.jpg" |
url, website |
"https://example.com" |
title (on Post/Article) |
Realistic short sentences |
content, body, description |
1-3 realistic sentences |
slug |
Derived from title: "realistic-short-sentence" |
price, amount |
Realistic numbers like 29.99, 149.00 |
quantity, count |
Small integers: 1-100 |
createdAt, updatedAt |
Dates spread over the last 90 days |
publishedAt |
Either null or a date after createdAt |
isActive, isPublished |
Mix of true/false |
role (enum) |
Distribute across valid enum values |
password |
Pre-hashed placeholder: "$2b$10$..." — never plaintext |
Constraints
@unique: Ensure every value is unique. Use index suffixes: "user1@example.com", "user2@example.com".
@id @default(cuid()): Omit from create calls — let the database generate them.
@default(now()): Omit or set explicit dates for predictable ordering.
@default(value): Omit to use the default, or set explicitly for variety.
- Enums: Only use values defined in the enum.
Int, Float: Respect @db.SmallInt, @db.Decimal(10,2) etc.
Relations
- One-to-many: Create the "one" side first, reference its ID on the "many" side.
- Many-to-many (implicit): Use
connect syntax after both sides exist.
- Self-referencing: Create root records first (no parent), then children pointing to them.
- Required relations: Always satisfy — never leave a required FK null.
- Optional relations: Mix of connected and null.
Output Template
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
// Clear existing data (reverse dependency order)
await prisma.comment.deleteMany();
await prisma.post.deleteMany();
await prisma.user.deleteMany();
// Seed in dependency order
const users = await Promise.all([
prisma.user.upsert({
where: { email: "elena.rodriguez@example.com" },
update: {},
create: {
email: "elena.rodriguez@example.com",
name: "Elena Rodriguez",
// ... fields
},
}),
// ... more users
]);
// Use createMany for bulk inserts where relations allow
await prisma.post.createMany({
data: [
{ title: "...", authorId: users[0].id },
// ...
],
});
console.log("Seeded: X users, Y posts, Z comments");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(() => prisma.$disconnect());
Scale Parameter
When the user specifies a count (e.g., "seed 50 users"), generate that many records. Default to 5-10 records per model. Use createMany for bulk inserts where possible. Wrap large seeds in a prisma.$transaction().
Upsert Pattern
Use upsert on a unique field to make the seed idempotent — safe to run multiple times.
Reference
See references/seed-patterns.md for dependency ordering details, realistic data patterns, and performance tips.
1---2name: db-seed-generator3description: Generate realistic database seed data from a Prisma schema. Use when asked to generate seed data, create test data, populate the database, seed the DB, or create fixtures.4---5
6# DB Seed Generator
7
8Before generating any output, read `config/defaults.md` and adapt all patterns, imports, and code examples to the user's configured stack.
9
10## Process
11
121. Read `schema.prisma` and extract all models, fields, types, constraints, relations, and enums.
132. Determine dependency order: models with no required relations first, then models that depend on them.
143. Generate a `prisma/seed.ts` file with realistic fake data that respects all constraints.
154. Output a ready-to-run seed file.
16
17## Dependency Ordering
18
19Build a directed graph of model dependencies from `@relation` fields. Topologically sort so parent records are created before children.
20
21```
22User (no deps) → create first
23Organization (no deps) → create first
24Post (depends on User) → create second
25Comment (depends on User, Post) → create third
26```
27
28If circular dependencies exist, use a two-pass approach: create records with required fields first, then update with optional relation fields.
29
30## Data Generation Rules
31
32### Field Name Conventions
33
34Generate realistic values based on field names:
35
36| Pattern | Generated value |
37|---|---|
38| `firstName` | `"Elena"`, `"Marcus"`, `"Priya"` |
39| `lastName` | `"Rodriguez"`, `"Chen"`, `"Okafor"` |
40| `name` (on User) | `"Elena Rodriguez"` |
41| `email` | `"elena.rodriguez@example.com"` |
42| `phone` | `"555-0101"`, `"555-0102"` |
43| `avatarUrl`, `imageUrl` | `"https://example.com/avatars/1.jpg"` |
44| `url`, `website` | `"https://example.com"` |
45| `title` (on Post/Article) | Realistic short sentences |
46| `content`, `body`, `description` | 1-3 realistic sentences |
47| `slug` | Derived from title: `"realistic-short-sentence"` |
48| `price`, `amount` | Realistic numbers like `29.99`, `149.00` |
49| `quantity`, `count` | Small integers: `1`-`100` |
50| `createdAt`, `updatedAt` | Dates spread over the last 90 days |
51| `publishedAt` | Either `null` or a date after `createdAt` |
52| `isActive`, `isPublished` | Mix of `true`/`false` |
53| `role` (enum) | Distribute across valid enum values |
54| `password` | Pre-hashed placeholder: `"$2b$10$..."` — never plaintext |
55
56### Constraints
57
58- **`@unique`**: Ensure every value is unique. Use index suffixes: `"user1@example.com"`, `"user2@example.com"`.
59- **`@id @default(cuid())`**: Omit from create calls — let the database generate them.
60- **`@default(now())`**: Omit or set explicit dates for predictable ordering.
61- **`@default(value)`**: Omit to use the default, or set explicitly for variety.
62- **Enums**: Only use values defined in the enum.
63- **`Int`, `Float`**: Respect `@db.SmallInt`, `@db.Decimal(10,2)` etc.
64
65### Relations
66
67- **One-to-many**: Create the "one" side first, reference its ID on the "many" side.
68- **Many-to-many** (implicit): Use `connect` syntax after both sides exist.
69- **Self-referencing**: Create root records first (no parent), then children pointing to them.
70- **Required relations**: Always satisfy — never leave a required FK null.
71- **Optional relations**: Mix of connected and null.
72
73## Output Template
74
75```typescript
76import { PrismaClient } from "@prisma/client";
77
78const prisma = new PrismaClient();
79
80async function main() {
81 // Clear existing data (reverse dependency order)
82 await prisma.comment.deleteMany();
83 await prisma.post.deleteMany();
84 await prisma.user.deleteMany();
85
86 // Seed in dependency order
87 const users = await Promise.all([
88 prisma.user.upsert({
89 where: { email: "elena.rodriguez@example.com" },
90 update: {},
91 create: {
92 email: "elena.rodriguez@example.com",
93 name: "Elena Rodriguez",
94 // ... fields
95 },
96 }),
97 // ... more users
98 ]);
99
100 // Use createMany for bulk inserts where relations allow
101 await prisma.post.createMany({
102 data: [
103 { title: "...", authorId: users[0].id },
104 // ...
105 ],
106 });
107
108 console.log("Seeded: X users, Y posts, Z comments");
109}
110
111main()
112 .catch((e) => {
113 console.error(e);
114 process.exit(1);
115 })
116 .finally(() => prisma.$disconnect());
117```
118
119## Scale Parameter
120
121When the user specifies a count (e.g., "seed 50 users"), generate that many records. Default to 5-10 records per model. Use `createMany` for bulk inserts where possible. Wrap large seeds in a `prisma.$transaction()`.
122
123## Upsert Pattern
124
125Use `upsert` on a unique field to make the seed idempotent — safe to run multiple times.
126
127## Reference
128
129See [references/seed-patterns.md](references/seed-patterns.md) for dependency ordering details, realistic data patterns, and performance tips.