The suprnova developer CLI shells into your application binary to drive
SeaORM's migration runner, so the same migration set executes whether you
run it from a developer terminal, from CI, or implicitly at server startup.
Use these commands to author migration files, apply them, roll back, and
keep your generated SeaORM entities in sync with the schema.
For the schema-authoring API (column types, indexes, foreign keys, the full
MigrationTrait), see Migrations. For inserting test
data after the schema lands, see Seeding.
make:migration
Generate a new migration file under src/migrations/ and wire it into the
Migrator in src/migrations/mod.rs.
<name> is normalised to snake_case. The generator recognises the
standard naming patterns and uses them to pick the DeriveIden enum:
create_<table>_table- scaffolds acreate_tablebodyadd_<column>_to_<table>- scaffolds a stub foralter_tabledrop_<table>_table- scaffolds adrop_tablebody- anything else - uses the name as the table identifier
Examples
Generated file
The file is written to src/migrations/m{YYYYMMDD}_{HHMMSS}_<name>.rs
(for example m20260530_142301_create_users_table.rs) and added to the
Migrator::migrations() vec.
use *;
;
Edit the generated file to declare your columns, indexes, and constraints.
The generated file uses SeaORM's builder. You can write the same migration
with the shorter schema builder,
suprnova::schema::Schema. See Migrations for both forms.
migrate
Run every pending migration in src/migrations/.
The CLI shells out to cargo run -- migrate so your app's Application
runner does the work - same binary, same Migrator, same database
connection that serve would use.
Running migrations...
Migrations completed successfully!
The application's serve and web:run subcommands auto-run migrate before
binding the socket unless you opt out with --no-migrate or set
SUPRNOVA_AUTO_MIGRATE_BEST_EFFORT=true to keep going past a failure.
A migration error during auto-migrate exits non-zero before the server
boots; see framework/src/app/mod.rs for the fail-closed contract.
suprnova serve runs migrate once when it starts and then runs the backend
with serve --no-migrate, so a restart of the backend does not migrate again.
Pass --migrate always to migrate on every restart, or --no-migrate to run
no migration. See suprnova serve.
migrate:status
Print the applied/pending state of every migration.
Migration status:
...SeaORM-formatted table of applied/pending migrations...
The body of the report comes from SeaORM's MigratorTrait::status, so the
exact formatting tracks the SeaORM version your app depends on.
migrate:rollback
Roll back the last applied migration (or the last N).
| Option | Default | Description |
|---|---|---|
--step <N> |
1 |
Number of migrations to roll back |
# Roll back one migration
# Roll back the last three
Rolling back 3 migration(s)...
Rollback completed successfully!
Each migration's down() runs in reverse application order. A failing
down() exits non-zero and leaves the rest of the chain untouched -
nothing further is attempted.
migrate:fresh
Drop every table in the database and re-run every migration from scratch.
WARNING: Dropping all tables and re-running migrations...
Database refreshed successfully!
This destroys all data in the connected database. It is meant for local development and test setup, not for any environment where the data matters.
The production guard
Outside production it runs immediately, with no prompt - dropping a local database is routine and a confirmation you always answer the same way trains you to stop reading it.
When APP_ENV resolves to production it demands two different kinds of
proof:
--forceproves intent at the moment you typed the command.- A typed confirmation on an interactive terminal proves a human is present.
The terminal requirement is the point of the second one. Without it,
echo production | suprnova migrate:fresh --force in a deploy script
would answer the prompt automatically, and the confirmation would be just
another flag. So a non-interactive stdin is refused even with --force.
Anything other than the exact environment name aborts before a single table is dropped.
The same gate applies to your application binary's own subcommand
(./app migrate:fresh --force), which is the one a production deploy
actually runs.
db:sync
Regenerate the SeaORM entity files in src/models/entities/ from the
current database schema, and (when a src/bin/migrate.rs exists) run
pending migrations first.
| Option | Description |
|---|---|
--skip-migrations |
Skip the migration pass and only regenerate entities |
--regenerate-models |
Overwrite src/models/<table>.rs files too, not just src/models/entities/<table>.rs |
What it does
- (Optional) Runs pending migrations. The default scaffold does not
ship a
src/bin/migrate.rs, so this step is a no-op and printsMigration binary not found, skipping migrations. In a default project, runsuprnova migratefirst, thensuprnova db:sync --skip-migrations. - Connects to
DATABASE_URL, introspects every user table (skippingseaql_migrationsand any name starting with_), and writes one entity file per table tosrc/models/entities/<table>.rs. - Writes a thin user-facing model file at
src/models/<table>.rs- but only if that file does not already exist, so your hand-written accessors, scopes, and observer hooks survive. --regenerate-modelsoverrides the protection in step 3 and overwrites those user files. Use it when you have not customised them yet, or when you have a backup.
Typical workflow
# 1. Author a migration
# (edit src/migrations/m..._create_posts_table.rs)
# 2. Apply it
# 3. Regenerate the entities so the new table is reachable from code
Why Suprnova diverges
Laravel has one global artisan that owns every framework command,
including db:seed. Suprnova splits this in two:
- The
suprnovadeveloper CLI (this chapter) owns project scaffolding, generators, and the migration commands. It is installed once per developer machine viacargo installand shells into your app binary to do work that needs the app'sMigrator. - A per-project
consolebinary, built from your project'ssrc/bin/console.rs, ownsdb:seed, your#[command]-annotated handlers,queue:work,schedule:run,workflow:work, and other one-shot tasks that need your app's bootstrap, container bindings, and registered observers.
Migration commands live on the developer CLI because they have a deterministic shape that does not depend on your bootstrap. Everything that needs your service container or your registered seeders lives on the per-project console binary. See Console for the full console surface.
db:seed
Run the seeders with suprnova db:seed. It runs every registered seeder, or
the one you name:
The CLI runs cargo run --quiet --bin console -- db:seed and passes the name
as --class=<name>. It does not check the name: your console binary owns the
seeder registry and reports an unknown seeder. The seeder registry, ordering
rules, and the --class matching are covered in Seeding. The
framework ships db:seed as a built-in console command, so your scaffold gets
it without any wiring on your side. You can also run it with
cargo run --bin console -- db:seed.
Summary
| Command | What it does |
|---|---|
suprnova make:migration <name> |
Scaffold a new migration file and register it in Migrator |
suprnova migrate |
Run pending migrations |
suprnova migrate:status |
Show applied/pending status |
suprnova migrate:rollback [--step N] |
Roll back the last N migrations (default 1) |
suprnova migrate:fresh |
Drop all tables and re-run every migration |
suprnova db:sync [--skip-migrations] [--regenerate-models] |
Regenerate SeaORM entities from the live schema |
suprnova db:seed [<seeder>] |
Run registered seeders, through the per-project console binary |
Next
- Migrations - the SeaORM form and the schema builder: tables, columns, indexes, foreign keys
- Seeding - authoring seeders and the
db:seedconsole command - Console - the per-project
consolebinary and#[command]handlers - Database - connections, drivers, transactions, the query builder
- CLI Overview - every
suprnovasubcommand at a glance
