Seed data
Use ptah seed to load one-off setup rows — development fixtures, demo
accounts, initial admin users — into an environment without putting them in
migration history. You need a built ptah binary, a reachable database, and a
directory of seed files.
ptah seed is the imperative data path: it runs each matching SQL file once
and records it in the schema_seeds table. For lookup tables whose exact
contents Ptah should converge on every migration, use
declarative reference data instead.
Name the seed files
Section titled “Name the seed files”Seed files follow the NNN_description.env.sql convention inside a seeds
directory (default ./seeds):
NNNis a numeric version; files apply in version order.envselects the environment:002_demo_users.dev.sqlapplies only with--env dev, and001_countries.all.sqlapplies in every environment.- A
.sqlfile in the directory that does not match the convention fails the run before anything is applied.
Starting state for the steps below:
seeds/ 001_countries.all.sql 002_demo_users.dev.sqlapp.db-- seeds/001_countries.all.sqlINSERT INTO countries (code, name) VALUES ('US', 'United States');INSERT INTO countries (code, name) VALUES ('DE', 'Germany');-- seeds/002_demo_users.dev.sqlINSERT INTO users (email, display_name) VALUES ('dev@example.com', 'Dev User');Apply seeds to an environment
Section titled “Apply seeds to an environment”ptah seed --db-url "sqlite://app.db" --env devExpected output includes:
=== SEED ===Database: sqlite://app.dbDialect: sqliteSeeds directory: seedsEnvironment: dev
Matching seeds: 2Applied seeds: 2Skipped seeds: 0Seeds completed successfully.Re-running the same command is a no-op, because both files are recorded in
schema_seeds:
Matching seeds: 2Applied seeds: 0Skipped seeds: 2Database seed data is already up to date.Add --verbose to list which files were applied or skipped, and
--seeds-dir <path> when the directory is not ./seeds.
Verify
Section titled “Verify”Query the tracker table:
sqlite3 app.db "SELECT seed_path, env FROM schema_seeds ORDER BY seed_path;"Expected output includes:
001_countries.all.sql|dev002_demo_users.dev.sql|devProtect production-like environments
Section titled “Protect production-like environments”--env prod and --env production are refused unless --allow-prod is set:
error: refusing to seed protected environment "prod" without --allow-prodThe command exits with code 2 (see Exit codes).
Adjust the protected set with repeatable --protected-env flags, and add
repeatable --protected-table flags to require --allow-prod whenever a seed
file targets a named existing table.
Edit an applied seed
Section titled “Edit an applied seed”schema_seeds records a SHA-256 checksum of each file’s bytes alongside its
path, and the next run reads it. A seed file that changed after it was applied
is refused rather than reported as skipped:
error: error applying seeds: seed 001_countries.all.sql changed after it wasapplied: recorded checksum 85d0..., current 5bbc...; add a new seed file withthe change, or pass --force to re-apply this oneThe command prints that on one line, and the two checksums are full SHA-256 hex digests; both are wrapped and elided here.
Adding a new seed file is the normal answer, for the same reason it is with
migrations: the rows the old file wrote are already in the database, and the new
file says what changes about them. --force re-applies the edited file and
records its new checksum.
Re-run seeds
Section titled “Re-run seeds”--forcere-runs seeds that are already recorded inschema_seeds, and is what gets past the checksum refusal above. PlainINSERTstatements then hit duplicate-key errors on tables with primary or unique keys.--idempotenttreats a duplicate-key conflict as already-applied data, using a per-file savepoint, so--force --idempotentre-runs cleanly over existing rows.
Limitations
Section titled “Limitations”- Seed files are plain SQL applied once per environment; there are no down files and no rollback command.
- Seeds are outside migration history:
ptah migrations hash,validate, and the revision table do not cover them.
Next steps
Section titled “Next steps”- Ptah should own a table’s exact contents: Reference data.
- Wiring seeds into a scripted environment setup: Native commands.
- A seed run failed: Troubleshooting.