Seed a live database
misata seed fills a real Postgres or SQLite database with realistic,
referentially-intact data. It reads your schema straight from the database —
tables, columns, and foreign keys — generates data that respects it, inserts
parents before children, and then verifies against the database itself that
every foreign key resolves. No schema file, no codegen step, no ORM.
pip install "misata[db]"
misata seed postgresql://localhost/myapp_dev
That's the whole thing. Point it at a connection string and it does the rest.
What it does, in order
- Reads the schema from the live database, including every foreign-key constraint.
- Plans the run: sorts tables so parents are inserted before children, and assigns proportional row counts (reference tables small, transaction and line-item tables larger).
- Generates and inserts deterministically from a fixed seed, so the same command produces the same data every time.
- Verifies integrity against the database — for every relationship it counts child rows whose foreign key has no matching parent, and reports zero orphans when the data holds up.
Safe by default
Seeding a database you can see is destructive if you are careless, so the defaults are conservative.
- If a target table already has rows,
misata seedrefuses rather than double-seeding or silently skipping. It tells you which tables and offers the two ways forward. --dry-runprints the full plan — tables, insert order, existing row counts, and what would be inserted — and writes nothing.
misata seed postgresql://localhost/myapp_dev --dry-run
# table existing will insert
1 customers 0 500
2 products 0 500
3 orders 0 1,250
3 table(s), 2 foreign key(s), inserted parents-first.
Common flags
| Flag | What it does |
|---|---|
--rows N | Base row count; reference and transaction tables scale from it. |
--truncate | Wipe target tables (children first) before seeding. |
--skip a,b | Leave named tables untouched (migrations, auth, lookup tables). |
--tables a,b | Seed only these tables. |
--dry-run | Print the plan and exit without writing. |
--seed N | Random seed for reproducibility (default 42). |
--yes | Skip the confirmation prompt (for scripts and CI). |
Skipping app-managed tables
--skip is for tables your application owns, like schema_migrations or an
auth table. If you skip a table that is the parent of a table you are
seeding, misata seed will also skip that child and tell you why: its foreign
keys would point at rows that do not exist, which would break the zero-orphan
guarantee. (Seeding children against rows that already exist in a skipped
parent — "append mode" — is on the roadmap.)
misata seed postgresql://localhost/myapp_dev --skip schema_migrations,ar_internal_metadata
Reset and reseed
The usual development loop is wipe-then-fill:
misata seed postgresql://localhost/myapp_dev --truncate --rows 500 --yes
Why the verification step matters
Most seeding tools stop at "it inserted". The failure that actually costs you
an afternoon is the one where a child row points at a parent that was never
inserted, and you only find out when a JOIN in your app returns nothing.
misata seed closes that gap by asking the database, after the fact, whether
every foreign key resolves — and printing the answer:
🔎 Verifying foreign keys against the database…
✓ orders.customer_id → customers.id — 0 orphan(s)
✓ orders.product_id → products.id — 0 orphan(s)
✓ Seeded 2,250 rows in 0.5s. Every foreign key resolves in the database.
Coming from a discontinued seeding tool
If your team relied on a seeding tool that is no longer maintained,
misata seed covers the core workflow — read the live schema, fill the
database with connected data, reset and repeat — as a free, open-source CLI
with no account and no codegen artifacts to keep in sync. Point it at your dev
database and it works from the schema that is already there.