How to Seed PlanetScale with Realistic Test Data
The Problem
PlanetScale provides serverless MySQL with branching and non-blocking schema changes. But its branching model means you regularly create new database branches that start empty or with only schema, no data. Development branches need realistic data to test queries, UI components, and business logic. Manually writing INSERT statements for every branch is a waste of engineering time.
Making things harder, PlanetScale's foreign key constraints work differently from traditional MySQL. You cannot use standard foreign key references, so your seed data needs to maintain referential integrity at the application level. Libraries like Faker.js generate random values but leave the relationship problem entirely to you.
The Solution: MockHero API
MockHero generates relationally-consistent data where ref fields guarantee that child records always reference valid parent IDs. The output works perfectly with PlanetScale's application-level referential integrity model. Request JSON and insert with the serverless driver, or request SQL and pipe it through the MySQL CLI.
Quick Setup
curl -X POST https://api.mockhero.dev/api/v1/generate \
-H "x-api-key: mh_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"tables": [
{
"name": "teams",
"count": 5,
"fields": [
{ "name": "id", "type": "uuid" },
{ "name": "name", "type": "company_name" },
{ "name": "plan", "type": "enum", "params": { "values": ["free","pro","enterprise"] } },
{ "name": "created_at", "type": "datetime" }
]
},
{
"name": "members",
"count": 25,
"fields": [
{ "name": "id", "type": "uuid" },
{ "name": "team_id", "type": "ref", "params": { "ref": "teams.id" } },
{ "name": "full_name", "type": "full_name" },
{ "name": "email", "type": "email" },
{ "name": "role", "type": "enum", "params": { "values": ["owner","admin","member","viewer"] } }
]
}
],
"format": "json"
}'
Step-by-Step Guide
1. Install dependencies
npm install @planetscale/database
2. Get your MockHero API key
Sign up at mockhero.dev/sign-up and grab your key from the dashboard.
3. Write the seed script
Create seed.mjs:
import { connect } from "@planetscale/database";
const conn = connect({
host: process.env.DATABASE_HOST,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
});
const res = await fetch("https://api.mockhero.dev/api/v1/generate", {
method: "POST",
headers: {
"x-api-key": process.env.MOCKHERO_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
tables: [
{
name: "teams",
count: 5,
fields: [
{ name: "id", type: "uuid" },
{ name: "name", type: "company_name" },
{ name: "plan", type: "enum", params: { values: ["free","pro","enterprise"] } },
{ name: "created_at", type: "datetime" },
],
},
{
name: "members",
count: 25,
fields: [
{ name: "id", type: "uuid" },
{ name: "team_id", type: "ref", params: { ref: "teams.id" } },
{ name: "full_name", type: "full_name" },
{ name: "email", type: "email" },
{ name: "role", type: "enum", params: { values: ["owner","admin","member","viewer"] } },
],
},
],
format: "json",
}),
});
const { data } = await res.json();
for (const t of data.teams) {
await conn.execute(
"INSERT INTO teams (id, name, plan, created_at) VALUES (?, ?, ?, ?)",
[t.id, t.name, t.plan, t.created_at]
);
}
for (const m of data.members) {
await conn.execute(
"INSERT INTO members (id, team_id, full_name, email, role) VALUES (?, ?, ?, ?, ?)",
[m.id, m.team_id, m.full_name, m.email, m.role]
);
}
console.log("Seeded", data.teams.length, "teams and", data.members.length, "members");
4. Run the script
node seed.mjs
5. Verify in the PlanetScale console
Open the Console tab in your PlanetScale dashboard and run SELECT m.full_name, t.name FROM members m JOIN teams t ON m.team_id = t.id LIMIT 10; to verify relationships.
Why MockHero vs Faker / Manual Seeds
- Branch-ready — run the same seed script against any PlanetScale branch for instant realistic data.
- Application-level FK integrity — MockHero's
reffields handle relationships at the data level, matching PlanetScale's model. - MySQL-compatible output — request
format: "sql"to get MySQL-flavored INSERT statements directly.
Get Started
Seed every PlanetScale branch with production-realistic data. Sign up free at mockhero.dev and get 1,000 rows per month.
MockHero Team
Guides and tutorials for generating realistic test data with the MockHero API.
Start generating test data for free
1,000 rows/month on the free tier. No credit card required.
Get Your API Key