From harness-claude
Seeds Prisma databases idempotently using prisma/seed.ts, upserts, environment branching, factories, and --seed flag for dev, test fixtures, reference, and demo data.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Seed databases idempotently with prisma/seed.ts, --seed flag, and environment branching
Generates idempotent TypeScript/SQL seed scripts from Drizzle, Prisma, or SQL schemas with realistic data respecting FKs, constraints, and D1 limits. For dev/demo/test DB population.
Manages Rails development and test data with seeds, fixtures, FactoryBot factories, idempotent patterns, and environment-specific strategies.
Share bugs, ideas, or general feedback.
Seed databases idempotently with prisma/seed.ts, --seed flag, and environment branching
prisma migrate resetprisma/seed.ts:import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
// Reference data — always needed
const adminRole = await prisma.role.upsert({
where: { name: 'ADMIN' },
update: {},
create: { name: 'ADMIN', permissions: ['read', 'write', 'delete'] },
});
// Development data — sample records
const user = await prisma.user.upsert({
where: { email: 'admin@example.com' },
update: {},
create: {
email: 'admin@example.com',
name: 'Admin User',
roleId: adminRole.id,
},
});
console.log({ adminRole, user });
}
main()
.then(() => prisma.$disconnect())
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
package.json:{
"prisma": {
"seed": "tsx prisma/seed.ts"
}
}
Use tsx or ts-node for TypeScript seeds. Ensure the runner is in devDependencies.
upsert instead of create so the seed can run multiple times without duplicating data:await prisma.category.upsert({
where: { slug: 'technology' },
update: { name: 'Technology' },
create: { slug: 'technology', name: 'Technology' },
});
async function main() {
await seedReferenceData(); // Always runs
if (process.env.NODE_ENV !== 'production') {
await seedDevelopmentData(); // Sample users, posts, etc.
}
if (process.env.SEED_DEMO === 'true') {
await seedDemoData(); // Curated demo content
}
}
npx prisma db seed
The seed also runs automatically after prisma migrate reset and prisma migrate dev (when a new migration is created).
function createRandomUser() {
return {
email: `user-${crypto.randomUUID()}@example.com`,
name: `User ${Math.random().toString(36).slice(2)}`,
};
}
await prisma.user.createMany({
data: Array.from({ length: 100 }, createRandomUser),
skipDuplicates: true,
});
Seed in correct dependency order — create parent records before children. For circular dependencies, create records without relations first, then update with connections.
Reset and reseed in one command:
npx prisma migrate reset --force
This drops the database, applies all migrations, and runs the seed script.
Prisma seeding runs as a standalone Node.js script invoked by the Prisma CLI. It has full access to Prisma Client and can include any business logic needed to set up the data.
Seed vs migration data: Reference data that must exist for the application to function (enum-like lookup tables, system config) belongs in migrations as INSERT statements, not in seeds. Seeds are for development convenience; migrations are for production correctness.
Performance for large seeds: createMany is significantly faster than individual create calls because it batches into a single INSERT with multiple value tuples. However, createMany does not support nested creates — use it for flat data and fall back to create for relational data.
Testing seeds: Create a separate seed function that returns the created data for use in integration tests:
export async function seedTestData(prisma: PrismaClient) {
const user = await prisma.user.create({ data: { ... } });
return { user };
}
Call this from your test setup with a transaction that rolls back after each test.
Common mistakes:
prisma.$disconnect() is not calledcreate instead of upsert — the seed fails on second runcuid() or let the database auto-generate. Hardcoded IDs collide across environmentsprisma.seed configuration in production imageshttps://prisma.io/docs/orm/prisma-migrate/workflows/seeding