Seeding Database Data
1. Creating Seed Script
// prisma/seed.ts
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
await prisma.user.upsert({
where: { email: "admin@example.com" },
update: {},
create: { email: "admin@example.com", role: "ADMIN" }
});
}
main().finally(() => prisma.$disconnect());
| Aspect | Detail |
| Idempotent | Use upsert / skipDuplicates |
| Order | Parents before children |
2. Configuring Seed Command
{
"prisma": { "seed": "tsx prisma/seed.ts" }
}
| Runner | Use |
| tsx | Fast TypeScript runner |
| ts-node | Mature |
| node | For compiled JS |
3. Running Seed Command
| Command | Detail |
prisma db seed | Manual execution |
migrate reset | Auto-runs seed |
migrate dev | Runs seed on first migration of empty DB |
4. Using Faker for Test Data
import { faker } from "@faker-js/faker";
const users = Array.from({ length: 50 }, () => ({
email: faker.internet.email(),
name: faker.person.fullName()
}));
await prisma.user.createMany({ data: users });
| Helper | Use |
internet.email | Random emails |
person.* | Names |
faker.seed(n) | Reproducible runs |
5. Implementing Idempotent Seeds
| Strategy | Detail |
| upsert by unique | Safe re-run |
| createMany + skipDuplicates | Bulk idempotency |
await prisma.user.create({
data: {
email: "demo@x.io",
posts: { create: [{ title: "Welcome" }, { title: "Hello" }] }
}
});
| Pattern | Detail |
| Nested create | One round-trip |
| Connect existing | Reuse seeded references |
7. Importing from CSV Files
import { parse } from "csv-parse/sync";
import { readFileSync } from "node:fs";
const rows = parse(readFileSync("data/users.csv"), { columns: true });
await prisma.user.createMany({ data: rows, skipDuplicates: true });
| Step | Detail |
| Parse | csv-parse / papaparse |
| Validate | Zod schema per row |
| Bulk insert | createMany in batches |
8. Creating Factory Functions
const userFactory = (overrides = {}) => ({
email: faker.internet.email(),
role: "USER",
...overrides
});
| Benefit | Detail |
| Reuse | Tests + seeds share factories |
| Override | Spread overrides for variants |
9. Handling Large Data Batches
| Tip | Detail |
| Chunk inserts | 1k-10k per batch |
| Disable triggers | If safe, for speed |
| COPY (PG) | Use raw SQL for millions of rows |
10. Resetting and Reseeding Database
| Command | Effect |
migrate reset | Drop, recreate, migrate, seed |
migrate reset --skip-seed | No seeding |