Skip to content

Database commands

This reference brings together Database inspection, generation, migration, seeding and cleanup commands. Run them from the project root with the Python environment and connection configured.

Each example pair shows two alternatives: orionis and python -B reactor. Run one of them. When managing the environment with uv, you can prefix the Python command with uv run.

OptionAvailable onDefault and effect
-h, --helpAll 14 commandsDisplays help without performing the operation or generating files.
--database NAME, -d NAMEThis page’s db:* and migrate* commandsNone: uses the default connection. NAME is a registered connection name, not a URL, file or table name.

The make:* generators do not accept --database: they create files using application paths. Configure the connection under Database configuration; examples using --database sqlite assume that connection is registered. An unknown connection, missing driver dependency or invalid credentials produces a resolution or execution error rather than automatically creating a different connection.

To inspect specific help:

Terminal window
orionis db:show --help
python -B reactor db:show --help
CommandPurpose
db:showShows a connection summary and its visible tables. Use it to confirm the target and understand its contents before migrating or inspecting a table.
db:tableInspects an existing physical table: connection, resolved name, row count, size, columns, indexes and foreign keys.
db:wipeRemoves discovered user objects from the selected connection. Use it to empty a development or test database when tables outside migration history must also be removed.
db:seedRuns pending seeders in discovery order. Use it after creating the tables required by their inserts.
make:database-migrationGenerates a migration file with empty async up() and down() methods. It neither runs the migration nor creates a table.
make:database-schemaGenerates a reusable table schema definition. It is a Python file usable by migrations; generation does not execute DDL.
make:database-seederGenerates a seeder with an empty async run() for initial data. It neither executes the seeder nor creates its table.
make:factoryGenerates a factory for an existing model. Its file defines sample attributes; the command does not generate records.
migrateApplies all pending migrations on the selected connection. This is the normal command after implementing a new migration.
migrate:statusShows each discovered migration, whether it ran, and its batch. Use it to check state before or after migrating.
migrate:rollbackReverts the latest applied migration batches through their down() methods. It does not reapply them.
migrate:resetReverts all migrations recorded as applied on the connection, calling down() in reverse order.
migrate:refreshReverts selected migrations, then applies all pending migrations. Use it to rebuild changes through the down()/up() cycle.
migrate:freshReverts all applied migrations, removes migration and seeder history tables, and applies discovered migrations again.

db:show [--database NAME] [--counts] [--views]

Shows a connection summary and its visible tables. Use it to confirm the target and understand its contents before migrating or inspecting a table.

Argument or specific optionTypeDefaultEffect
--countsboolFalseAdds a COUNT(*) for each table; this may be expensive on large databases.
--viewsboolFalseAdds a list of available regular and materialized views.

Also accepts --database/-d and --help/-h.

Terminal window
orionis db:show
python -B reactor db:show
Terminal window
orionis db:show --database sqlite --counts --views
python -B reactor db:show --database sqlite --counts --views

The first table displays Connection, Driver, Database, Size, Open connections, Tables, Views and Materialized views. Table names and sizes follow; --counts adds Rows. Without --views, view totals still appear in the summary, but their names are not listed.

Sizes use B/KiB/MiB/GiB/TiB. N/A means a metric is unavailable, rather than zero. There is no JSON output or table-filter flag. An empty catalog is reported without creating application tables.

db:table table [--database NAME]

Inspects an existing physical table: connection, resolved name, row count, size, columns, indexes and foreign keys.

Argument or specific optionTypeDefaultEffect
tablestrRequiredTable name shown by db:show; this is not a model class name.

Also accepts --database/-d and --help/-h.

Terminal window
orionis db:table products --database sqlite
python -B reactor db:table products --database sqlite

Columns show name, type, nullable, default and primary-key membership. Indexes include name, columns, uniqueness and a primary-key marker; foreign keys include column, reference and ON DELETE. Missing indexes or foreign keys produce explicit messages.

db:table always counts rows: it has neither --counts nor a flag to skip that count. This can be expensive on a large table. DB_PREFIX is not automatically added to the supplied name.

On PostgreSQL, Redshift and SQL Server use schema.table when an unqualified name is ambiguous: for example public.products or dbo.products, if they exist. Oracle resolves names from its user catalog. Object names containing additional periods cannot be represented unambiguously on the three schema-qualified engines.

A missing table or ambiguous/invalid name produces an error message and exit 1; successful inspection returns 0. Connection or permission failures propagate from Database. This command does not inspect views. Redshift lists no indexes, and displayed PK/FK declarations are informational rather than a guarantee of engine enforcement.

db:wipe [--database NAME] [--force]

Removes discovered user objects from the selected connection. Use it to empty a development or test database when tables outside migration history must also be removed.

Argument or specific optionTypeDefaultEffect
--forceboolFalseSkips interactive confirmation. Required when stdin is not a terminal.

Also accepts --database/-d and --help/-h.

Terminal window
orionis db:wipe --database sqlite
python -B reactor db:wipe --database sqlite

Without --force, confirmation defaults to no. Declining returns 0 and reports cancellation. Without a terminal, it returns 1 without deleting anything and explains that --force is required. Success returns 0 and displays removed table, view and type counts.

For automation deliberately intended to empty that connection, the non-interactive form is:

Terminal window
python -B reactor db:wipe --database sqlite --force

--force does not validate the environment or guarantee rollback; it only skips the prompt. The command has no additional APP_ENV protection. Catalog visibility and database-user permissions determine which objects it can discover and remove. Removal is not limited to the framework table prefix.

EngineBehavior verified in the implementation
SQLiteViews and tables within a transaction; defers foreign keys until commit to allow cyclic references. Does not enumerate internal sqlite_ objects as targets and retains the database file.
MySQL / MariaDBViews and tables; reserves the same physical connection, temporarily disables FOREIGN_KEY_CHECKS and restores its prior value in finally. DDL commits implicitly, so the entire wipe cannot be guaranteed to roll back.
PostgreSQLMaterialized views, views, tables, domains and user types; uses a transaction and CASCADE where applicable. Dependent objects may also be affected.
RedshiftMaterialized views, views and tables through its specific catalog; uses a transaction and CASCADE where applicable. Its catalog is not treated as PostgreSQL’s.
SQL ServerOrders view/type dependencies, disables SYSTEM_VERSIONING on temporal tables and removes foreign keys before tables; uses a transaction. Unresolvable dependencies may stop the operation.
OracleUser materialized views, views, tables and types; checks type dependencies before removal and refreshes the table list after dropping materialized views. DDL commits implicitly, so failure may leave a partial wipe.

On Oracle, external dependencies or type cycles may prevent wiping. --force does not bypass these restrictions: DROP TYPE FORCE is not used.

This command does not drop the database or server user, nor guarantee removing every object category offered by each engine. Summary counts describe discovered categories; CASCADE may affect additional dependencies.

db:seed [--database NAME]

Runs pending seeders in discovery order. Use it after creating the tables required by their inserts.

Also accepts --database/-d and --help/-h.

Terminal window
orionis db:seed --database sqlite
python -B reactor db:seed --database sqlite

This is an alias of seed, with the same options and behavior. Completed seeders are recorded in seeders; invoking it again does not repeat recorded files. It displays per-file progress or a message indicating nothing is pending.

Each seeder uses its own transaction. Failure rolls back its changes and history record; earlier seeders may already be committed. Redshift rejects the runner because it cannot guarantee its UNIQUE claim. The command accepts neither a class name nor --class, --force or --count. See Seeders for ordering, history and complete examples.

make:database-migration name

Generates a migration file with empty async up() and down() methods. It neither runs the migration nor creates a table.

Argument or specific optionTypeDefaultEffect
namestrRequiredDescriptive name, optionally including subdirectories.

Also accepts --help/-h.

Terminal window
orionis make:database-migration create_products
python -B reactor make:database-migration create_products

With default paths it creates database/migrations/m<YYYYmmddHHMMSS>_create_products.py, containing class CreateProducts. The timestamp uses the application timezone; do not type <YYYYmmddHHMMSS> literally in the command.

It also accepts catalog/create_products. Implement up() and down() before running migrate; the generator does not infer operations from the name. It has no --create, --table, --database or --force flags. See Migrations for the full workflow.

make:database-schema name

Generates a reusable table schema definition. It is a Python file usable by migrations; generation does not execute DDL.

Argument or specific optionTypeDefaultEffect
namestrRequiredModule name; appends Schema to the filename when absent.

Also accepts --help/-h.

Terminal window
orionis make:database-schema products
python -B reactor make:database-schema products

With default paths it generates database/schemas/products_schema.py. Subdirectories such as catalog/products are also supported. Since 1.0.10, the stub contains a module constant without a holder class:

from typing import Final
from orionis.orm.schema import TableDefinition
TABLE: Final[TableDefinition | None] = None

Replace None with a TableDefinition, import TABLE in the migration, and apply it with await Schema.createFromDefinition(TABLE). It neither generates an ORM model nor automatically applies the schema. Only name and help are supported. See Creating schemas and tables.

make:database-seeder name

Generates a seeder with an empty async run() for initial data. It neither executes the seeder nor creates its table.

Argument or specific optionTypeDefaultEffect
namestrRequiredFile and class name; appends Seeder when absent.

Also accepts --help/-h.

Terminal window
orionis make:database-seeder initial_products
python -B reactor make:database-seeder initial_products

With default paths it creates database/seeders/initial_products_seeder.py and InitialProductsSeeder. Nested names such as catalog/initial_products are accepted.

Implement run() and execute db:seed once the tables exist. Only name and help are supported; there are no model, overwrite or count flags. See Seeders.

make:factory name [--model MODEL]

Generates a factory for an existing model. Its file defines sample attributes; the command does not generate records.

Argument or specific optionTypeDefaultEffect
namestrRequiredFactory name, optionally nested; appends Factory when absent.
--model, -mstrNoneModel relative to app/models. When omitted, derived by removing Factory and retaining subdirectories.

Also accepts --help/-h.

Terminal window
orionis make:factory ProductFactory --model Product
python -B reactor make:factory ProductFactory --model Product
Terminal window
orionis make:factory catalog/ProductFactory --model catalog/Product
python -B reactor make:factory catalog/ProductFactory --model catalog/Product

The first example creates database/factories/product_factory.py, class ProductFactory, and an import of app.models.product.Product. The second uses the corresponding catalog directories. Targets are resolved through configured database_factories and app_models paths.

The generator does not check whether the model module exists: a syntactically valid name may create an import that fails later if the file is missing. The stub includes model = Product and synchronous definition() returning {}. Implement the attributes: the command does not generate the model or create its table, and accepts neither --count nor --force. Build or persist data later through make()/create() in code; see Factories.

migrate [--database NAME] [--seed]

Applies all pending migrations on the selected connection. This is the normal command after implementing a new migration.

Argument or specific optionTypeDefaultEffect
--seedboolFalseRuns pending seeders after migrations complete successfully.

Also accepts --database/-d and --help/-h.

Terminal window
orionis migrate --database sqlite
python -B reactor migrate --database sqlite
Terminal window
orionis migrate --database sqlite --seed
python -B reactor migrate --database sqlite --seed

Pending migrations in one invocation share a batch; each file uses its own transaction. The CLI displays RUNNING/DONE/FAIL lines with timings, or indicates there is nothing pending.

--seed also runs seeders when migrations were already up to date. Seeder failure does not undo previously committed migrations. There are no --step, --force or --pretend flags. See Migrations for history, discovery and transactions.

migrate:status [--database NAME]

Shows each discovered migration, whether it ran, and its batch. Use it to check state before or after migrating.

Also accepts --database/-d and --help/-h.

Terminal window
orionis migrate:status --database sqlite
python -B reactor migrate:status --database sqlite

The table contains Migration, Status (Ran or Pending) and Batch (- for pending files). If no files are discovered, it reports that explicitly.

It does not execute up() or down(), but may create the migrations history table if absent. It is therefore not strictly write-free and does not inspect tables outside migration history. Use db:show for that purpose.

migrate:rollback [--database NAME] [--step N]

Reverts the latest applied migration batches through their down() methods. It does not reapply them.

Argument or specific optionTypeDefaultEffect
--step, -sint1 effectivePositive batch count. When omitted, the command uses 1.

Also accepts --database/-d and --help/-h.

Terminal window
orionis migrate:rollback --database sqlite
python -B reactor migrate:rollback --database sqlite
Terminal window
orionis migrate:rollback --database sqlite --step 2
python -B reactor migrate:rollback --database sqlite --step 2

--step counts batches, not files. If N exceeds the available count, all available batches are selected. Migrations revert in reverse application order, with one transaction per file. Nonpositive counts are rejected; a failure stops execution, and previously committed reversions are not undone as one unit.

When reversal removes the last applied migration, the runner also drops that connection’s seeder history table. Partial rollback preserves it. There is no seeder down() automatically undoing seeded data. Actual data removal depends on each migration’s down().

migrate:reset [--database NAME]

Reverts all migrations recorded as applied on the connection, calling down() in reverse order.

Also accepts --database/-d and --help/-h.

Terminal window
orionis migrate:reset --database sqlite
python -B reactor migrate:reset --database sqlite

It does not apply migrations after reverting. It does not remove unrelated tables by catalog discovery; each down() may perform its own operations, so its implementation determines removed objects. When reverting the last applied migration, it drops the seeder history table. The migrations table remains empty. If there were no applied migrations, it does not perform that additional cleanup.

Only connection selection and help are supported. It accepts neither --step nor --seed, and does not ask for specific confirmation before running down(). Use migrate:rollback for partial reversal.

migrate:refresh [--database NAME] [--step N]

Reverts selected migrations, then applies all pending migrations. Use it to rebuild changes through the down()/up() cycle.

Argument or specific optionTypeDefaultEffect
--step, -sintNoneWhen omitted, reverts all applied migrations. When supplied, reverts the latest N batches; N must be positive.

Also accepts --database/-d and --help/-h.

Terminal window
orionis migrate:refresh --database sqlite
python -B reactor migrate:refresh --database sqlite
Terminal window
orionis migrate:refresh --database sqlite --step 1
python -B reactor migrate:refresh --database sqlite --step 1

The apply phase is not limited to just-reverted files: it executes every migration pending at that point. There is no global transaction spanning both phases. --seed is unsupported; use db:seed afterwards.

It may delete data because it runs down(). It has neither its own confirmation nor --force. It does not rebuild history infrastructure as migrate:fresh does: the migrations table remains and reverted records are removed. Reverting the last applied migration also drops the seeders table.

migrate:fresh [--database NAME]

Reverts all applied migrations, removes migration and seeder history tables, and applies discovered migrations again.

Also accepts --database/-d and --help/-h.

Terminal window
orionis migrate:fresh --database sqlite
python -B reactor migrate:fresh --database sqlite

The new migration history starts at batch 1. It is not equivalent to db:wipe: it uses migration down() methods rather than dropping every catalog table. An unrelated table remains unless those methods remove it.

It accepts neither --seed, --step nor --force, asks for no dedicated confirmation and does not run seeders. Execute db:seed explicitly afterwards when required. A failing down() or new migration interrupts execution; there is no global rollback spanning all phases.

All four make:* commands require name, create necessary directories and do not overwrite an existing file. They accept nested relative names using / or \ and validate Python module names; absolute paths and traversal components such as .. are rejected. Module names are normalized and Schema/Seeder/Factory suffixes are appended only when absent. Use snake_case for migrations and consistent file/class names.

Displayed paths are defaults: database_migrations, database_schemas, database_seeders and database_factories may point elsewhere in the application. File generation does not record execution in migrations or seeders; the corresponding runner does that.

ResultObserved CLI exit code
Help or successful operation0
Declining db:wipe confirmation0, without deleting
Missing table, wipe without a terminal when —force is omitted, or runner exception1
Missing required argument, unknown flag or unparseable value2
Generator error caught by MakeStubCommandMay return 0 despite displaying an error

Generators catch and print OSError, TypeError and ValueError; their return does not distinguish these failures from success. In automation, verify the creation message and expected file, rather than relying only on exit 0. Existing files are not overwritten. Defaults in the tables above describe effective behavior: an internal missing-value marker displayed by help is not a value to pass.

Migrations use per-file transactions, but DDL rollback depends on the engine; MySQL and Oracle have implicit commits. The CLI does not turn an entire refresh/fresh operation into a global transaction.

CommandRuns down()Applies pending migrations afterwardsRemoves complete historyDiscovers and removes unrelated tables
migrate:rollbackLatest N batchesNoRemoves reverted records; clears seeders when emptyNo; depends on down() contents
migrate:resetAll applied migrationsNoRetains empty migrations; drops seeders when reverting the last applied migrationNo; depends on down() contents
migrate:refreshAll or latest N batchesYesRetains migrations; drops seeders if reversal removes every applied migrationNo; depends on down() contents
migrate:freshAll applied migrationsYesRemoves migrations and seeders tables; new batch 1No; depends on down() contents
db:wipeNoNoRemoves those tables if discovered in the catalogYes, within the visible catalog

The four migrate:* commands running down() do not request the interactive confirmation used by db:wipe. Their data effects depend on migrations. These commands have no --force flag: do not add it based on another CLI’s conventions.

Read more under Migrations, Seeders, Factories, transactions and isolated database testing.