Command Line Tools
Database
Three commands cover day-to-day database work: wheels migrate applies migration files, wheels seed populates default records, and wheels db bundles utility subcommands for status, version, and reset. All three delegate to a running Wheels server over HTTP — start one with wheels start before running any of them.
You’ll use this for:
- Applying pending migrations after generating a model or editing a migration file.
- Seeding development or production data from
app/db/seeds.cfmand its environment-specific siblings. - Inspecting which migrations have been applied, or rolling forward pending ones after pulling a branch.
- Resetting an embedded development database to a known-good state during iteration.
wheels migrate
Section titled “wheels migrate”Apply or roll back migration files in app/migrator/migrations/.
Synopsis
Section titled “Synopsis”wheels migrate [latest|up|down|info|doctor|forget|pretend|unlock|rename-system-tables|diff]Running wheels migrate with no subcommand defaults to latest. An unknown subcommand prints Invalid value '<name>' for action. Valid values: latest, up, down, info, doctor, forget, pretend, unlock, rename-system-tables, diff. and exits non-zero without touching the schema.
Subcommands
Section titled “Subcommands”latest
Section titled “latest”Runs every pending migration in order until the database is caught up with the migrations directory. This is the command you reach for most often — after generating a model, after pulling a branch that added migrations, after writing a new migration by hand.
Runs the next pending migration and stops. Use this when you want to advance one step at a time rather than applying everything at once.
Rolls back the most recently applied migration by calling its down() method. Use this to undo a schema change you just applied, then edit the migration file and re-run up.
Prints a summary of applied and pending migrations without changing the schema. For the full tabular breakdown — version, description, status, applied-at timestamp — use wheels db status instead.
doctor
Section titled “doctor”Single-command health report for the migration tracking table. Lists orphan tracking rows (versions recorded as applied with no matching file on disk) and pending local migrations. Pure read — it changes nothing.
forget
Section titled “forget”Deletes a stale tracking row: wheels migrate forget <version> --yes. Dry-run by default; --yes is required to mutate. Refuses if a matching local migration file exists, or if the version isn’t in the tracking table. Refusals exit non-zero.
pretend
Section titled “pretend”Records a version as applied without running its up(): wheels migrate pretend <version> --yes. Dry-run by default; --yes is required to mutate. Refuses if the version is already applied or has no matching file. Refusals exit non-zero.
unlock
Section titled “unlock”Shows who holds the migration lock: the host, its owner id, how long it has held the lock and when its lease expires. Instances that share a database take turns running migrations under this lock. An instance that dies while holding it blocks the others until its lease runs out (migrationLockLease, default 3600 seconds).
- Nothing holds the lock, or the holder’s lease has expired: exits 0. The next migration takes over an expired lease.
- A live instance holds it: removes nothing and exits non-zero, naming the command that does.
wheels migrate unlock # who holds the lock; changes nothingwheels migrate unlock --force # remove it--force removes the lock whoever holds it and prints what it removed. Use it only when that instance is gone: a holder that is still running fails its next migration step with Wheels.MigrationLockLost. --yes doesn’t remove it: only --force does, on the command line and through MCP, where the migrate tool’s unlock action only reports unless force is true.
rename-system-tables
Section titled “rename-system-tables”Migrates legacy framework bookkeeping tables (c_o_r_e_*) to their current wheels_-prefixed names. Run once when upgrading a project whose system tables predate the current naming. Add --dry-run to preview the renames without writing.
Diffs your models against the live schema via AutoMigrator and prints the would-be changes without writing anything. Add --write to emit migration files instead. This is the read-only way to answer “what would migrations say if I generated them now?” — it never mutates the database.
| Flag | Default | Description |
|---|---|---|
--model=<Name> | all models | Diff a single model instead of every model. The model name can also be passed positionally: wheels migrate diff Post. |
--rename=<OLD:NEW> | — | Repeatable rename hint; use Model.OLD:NEW when diffing all models. |
--hints=<json> | — | Rename hints as JSON: {"renames":{"old":"new"}}. |
--threshold=<n> | — | Heuristic rename-detection threshold between 0 and 1. |
--name=<Name> | — | Migration name when writing a single-model diff with --write. |
--write | off | Write migration file(s) instead of previewing. |
wheels migrate diff --rename=Post.slug:Post.permalinkThe dbmigrate diff alias is equivalent to wheels migrate diff.
Example
Section titled “Example”wheels migrate latestPrints Running migration: latest... in cyan, dispatches the run to the server, and prints the migrator’s output: one block per migration applied, or Database is currently at version <version>. No migration required. when nothing is pending. Migration errors are reported as Migration failed: <message> — and the command exits non-zero, so a wheels migrate latest && ... CI gate does not proceed as if the schema moved.
wheels seed
Section titled “wheels seed”Populate the database from app/db/seeds.cfm and any environment-specific seed file.
Synopsis
Section titled “Synopsis”wheels seed [--environment=<env>] [--mode=<mode>] [--generate] [--models=<list>] [--count=<n>]The seeder runs app/db/seeds.cfm first (shared across every environment) and then app/db/seeds/<environment>.cfm if one exists. Both are wrapped in a single transaction. Seeds use the seedOnce() helper, which checks uniqueProperties before inserting — re-running is safe.
| Flag | Default | Description |
|---|---|---|
--environment=<env> | auto-detected | Load app/db/seeds/<env>.cfm after the shared seeds file. When omitted, the server uses the active Wheels environment. |
--mode=<mode> | auto | Seeder mode: auto, convention, or generate. convention runs the seed files. generate creates random test data for your models. auto runs the seed files when app/db/seeds.cfm or an environment seed file exists, and falls back to generate when none does. |
--generate | off | Shortcut for --mode=generate. Convention-based seeds (seedOnce()) are preferred. |
--models=<list> | every model under app/models | Generate mode only: comma-delimited model names to generate data for. |
--count=<n> | 10 | Generate mode only: records to create per model. |
Example
Section titled “Example”wheels seedPrints Running database seeds... and then a count like Seeded: 12 created, 3 skipped — the skipped count reflects rows that seedOnce() found already present.
wheels seed --environment=productionRuns app/db/seeds.cfm plus app/db/seeds/production.cfm. Useful for reference data (roles, statuses, lookup values) that must exist in production but shouldn’t ship as dev fixtures.
See the Seeding guide for the full seedOnce() API and file-layout conventions.
wheels db
Section titled “wheels db”Utility subcommands for migration status, schema version, and full-reset workflows.
Synopsis
Section titled “Synopsis”wheels db <command> [flags]Running wheels db with no subcommand prints a usage banner and exits non-zero. An unknown subcommand prints Invalid value '<name>' for subcommand. Valid values: reset, status, version. and exits non-zero.
Subcommands
Section titled “Subcommands”Runs pending migrations and reseeds the database in one shot. Destructive in the sense that it will apply every pending migration — but it does not drop existing tables. Requires --force to confirm; without it, the command prints a warning and exits without acting.
| Flag | Default | Description |
|---|---|---|
--force | off | Required. Confirms you want to migrate and reseed. |
--skip-seed | off | Run migrations but skip the seeding step. |
wheels db reset --forcePrints Running migrations..., dispatches wheels migrate latest, then prints Running seeds... and dispatches wheels seed. Ends with Database reset complete. in green. A migration or seed failure exits non-zero so the error is visible in scripts and CI.
status
Section titled “status”Prints a table of every migration — version, description, status (applied or pending), and applied-at timestamp.
| Flag | Default | Description |
|---|---|---|
--pending | off | Show only migrations that have not yet been applied. |
wheels db statusOutput is a formatted table with a totals line at the bottom (Total: 14 | Applied: 12 | Pending: 2). Applied rows are green; pending rows are yellow.
version
Section titled “version”Prints the current schema version.
| Flag | Default | Description |
|---|---|---|
--detailed | off | Also show the last applied migration, total migration count, pending count, and the next pending migration. |
wheels db version --detailedPrints the current version followed by a summary block — last applied migration with timestamp, totals, and the next pending migration if one exists.
Common workflows
Section titled “Common workflows”Fresh development setup
Section titled “Fresh development setup”wheels migrate latestwheels seedApply all migrations, then load the shared and development seed files. Run this after cloning a repo or pulling a branch that added migrations or seed data.
Reset the dev database to a clean slate
Section titled “Reset the dev database to a clean slate”wheels db reset --forceRuns pending migrations and reseeds in one command. Skip seeding with wheels db reset --force --skip-seed when you want the schema up to date but no data loaded.
Check what’s pending before applying
Section titled “Check what’s pending before applying”wheels db status --pendingwheels migrate latestPrint only the pending migrations first — useful for a quick sanity check on a branch switch — then apply them.
Seed production reference data
Section titled “Seed production reference data”wheels seed --environment=productionRuns app/db/seeds.cfm (shared) followed by app/db/seeds/production.cfm. Because seedOnce() is idempotent, running this after a deploy is safe even if the records already exist.