Here's a bug I've shipped more than once: tests pass locally, demo looks great,
then something breaks the moment real relational data shows up. The culprit is
almost always the same — seed data with foreign keys that don't actually
point at anything.
The quiet problem with hand-rolled seed data
Say you've got the classic Prisma setup:
model User {
id Int @id @default(autoincrement())
email String @unique
posts Post[]
}
model Post {
id String @id @default(uuid())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}
When you fake seed data for Post, what goes in authorId? If you're using a
generic faker-style approach, you get a random integer. It looks fine in a
JSON preview. But:
- A
JOINbetweenPostandUserreturns rows that shouldn't exist, or none at all. - A real FK constraint in Postgres rejects the insert outright (
violates foreign key constraint). - Any UI that renders "post by author" either crashes or shows ghosts.
Your seed data passed the eyeball test and failed the only test that matters:
does it behave like real data?
Why "just use faker" isn't enough
faker (and the dozens of wrappers around it) are great at generating values —
names, emails, prices. What they don't understand is relationships. They'll
happily put authorId: 8471 on a post when no user 8471 exists, because they
generate each field in isolation. The value is realistic; the relationship is
fiction.
To generate honest relational data you need to:
- Generate the parent rows first (
User), and remember their real ids. - Generate the child rows (
Post), and set eachauthorIdto an id that was actually generated for a user.
It's not hard conceptually — it's just annoying to do by hand every single time
you touch the schema, which is exactly why people skip it and ship dangling keys.
Automating it
I got tired of writing this glue, so I built a small VS Code extension,
SeedForge,
that reads your schema.prisma and generates the data for you. The free
edition handles single-table generation with realistic typed values and exports
to JSON / SQL / CSV. The part relevant to this post — generating related tables
so the child's FK column points at a real generated parent — is what I spent the
most time getting right, because it's the thing generic tools skip.
It's also on Open VSX if you're
on Cursor / VSCodium.
The takeaway, tool or no tool
Even if you never touch SeedForge: next time you write seed data, ask whether
your foreign keys reference rows that exist. If they don't, your tests are
rehearsing against a world that can't happen in production. Generate parents
first, reuse their real ids for children, and your JOINs will finally tell
you the truth.
What's your approach to relational test data — hand-written factories, SQL
fixtures, something else? Genuinely curious what's working for people.
Top comments (0)