Skip to content

D1 Seed

How Tamer loads reference / default rows into D1, separate from schema migrations.

Seed is for mutable “current desired data” (lookup tables, feature-flag defaults, a bootstrap identity row). Migrations are immutable schema history. Do not put seed INSERTs in migration files — reset/provision would replay a historical snapshot instead of your current seed.

Tamer does not own application init (admins, invites, password hashing). Products that need a first operator typically seed a non-usable identity and claim it via the app (e.g. forgot-password).

Seed files

Each D1 / shard group that should be seeded declares a seedDir of .sql files:

db/system/seed/
  0001_defaults.sql
  0002_bootstrap_admin.sql
  • Naming: Tamer runs files in lexical order (same convention as migrations — zero-pad prefixes).
  • Format: plain .sql passed to wrangler d1 execute --file.
  • Idempotency: author-owned. Prefer INSERT … ON CONFLICT / upserts so tamer seed is safe to re-run. Tamer does not track applied seed files.
ts
workers: {
  api: {
    resources: {
      d1: [{
        logicalName: "app-db",
        type: "single",
        binding: "APP_DB",
        migrationsDir: "db/app/migrations",
        seedDir: "db/app/seed",
      }],
    },
  },
},

WFP tenant templates use the same field on shardGroups[] and d1[]:

ts
wfp: {
  namespaces: {
    myapp: {
      workers: {
        tenant: {
          main: "apps/tenant/src/index.ts",
          shardGroups: [{
            name: "primary",
            binding: "DB",
            migrationsDir: "db/primary/migrations",
            seedDir: "db/primary/seed",
          }],
          d1: [{
            logicalName: "system",
            binding: "DB_SYSTEM",
            migrationsDir: "db/system/migrations",
            seedDir: "db/system/seed",
          }],
        },
      },
    },
  },
},

Where seed runs

D1 kindDeclared onSeeded by
Stack single D1resources.d1[]tamer seed
Stack shard groupresources.shardGroups[]tamer seed
Per-tenant utility D1wfp…workers.<svc>.d1[]tamer wfp tenant seed
Tenant shard groupwfp…workers.<svc>.shardGroups[]tamer wfp tenant seed

Also auto-runs after migrate on:

  • tamer wfp tenant provision (default on; --no-seed to skip)
  • tamer wfp tenant reset / tamer reset
  • tamer wfp tenant add-shard / tamer shard add (new shard only)

Seed does not run after every standalone tamer migrate — that would risk clobbering user-edited rows on routine schema deploys. Use tamer seed / wfp tenant seed when you change seed files on an existing DB.

Commands

bash
tamer seed --env dev
tamer seed --env dev --worker api

tamer wfp tenant seed --env dev --workspace acme
tamer wfp tenant seed --env local --workspace localdev

Non-local envs use --remote. Stack tamer seed --env local and wfp tenant seed --env local both target wrangler’s local SQLite cache (tenant: under the WFP template worker dir — see Local Development).

Secrets

Do not put real passwords in seed SQL (files live in git). Seed identity (email + role + unusable hash / must-reset flag); claim via the app.

See also

  • Migrations — schema history (migrationsDir)
  • Lifecycle — apply / migrate / seed / deploy ordering

Released under the Tamer Evaluation License.