db:migrate
Generate Alembic migration scripts for all features or a single one.
Usage
splent db:migrate [FEATURE] [-m MESSAGE]
Options
| Option | Description |
|---|---|
-m |
Migration message (defaults to feature name). |
--empty |
Generate a blank migration (no autogenerate) and keep it for manual editing. Requires a FEATURE argument. Use it for refinement features that add columns to a base feature’s table. Alembic cannot autodetect runtime-injected mixins, so the empty migration would otherwise be removed. |
Examples
Migrate all features.
splent db:migrate
Migrate a single feature with a descriptive message.
splent db:migrate splent_feature_notes_tags -m "add tags column to notes"
Create a blank migration to edit by hand (refinement features).
splent db:migrate splent_feature_notes_tags --empty -m "add tags column to notes"
Description
For each feature (or the specified one), this command does the following.
- Generates new migration scripts by comparing the current models against the database schema (
alembic revision --autogenerate). - Detects empty migrations (no schema changes) and removes them automatically, preventing accumulation of stub files with only
pass.
Each feature uses an isolated Alembic version table named alembic_<feature_name>, so migrations never interfere with each other.
Migration directories are resolved via the product’s features/ symlinks first, falling back to importlib for pip-installed features.
db:migrateonly generates migration files. It does not apply them. Usedb:upgradeto apply pending migrations after reviewing the generated files.
Refinement features
Refinement features add columns to a base feature’s table through a mixin that is injected at runtime (refine_model). Alembic’s autogenerate compares the base models against the database and therefore does not see those mixin columns. A plain db:migrate would generate an empty migration and remove it automatically.
For these features, generate a blank migration with --empty and write the upgrade()/downgrade() by hand.
splent db:migrate splent_feature_notes_tags --empty -m "add tags column to notes"
Then edit the generated file in migrations/versions/, targeting the base feature’s table (e.g. notes, not notes_tags).
def upgrade():
op.add_column("notes", sa.Column("tags", sa.String(500), nullable=True))
def downgrade():
op.drop_column("notes", "tags")
Apply it with db:upgrade. See Tutorial 6 (Extend with refinement) for the full walkthrough.
Migration order
Migrations are applied in dependency order based on UVL constraints. For example, if profile => auth is declared in the UVL file, auth migrations run before profile.
Migration system
SPLENT uses a per-feature migration layout.
src/splent_io/<feature>/
└── migrations/
├── alembic.ini
├── env.py
├── script.py.mako
└── versions/
The central tracking table.
CREATE TABLE splent_migrations (
feature VARCHAR(255) NOT NULL,
last_migration VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (feature)
);
Requirements
SPLENT_APPmust be set.- The database must be reachable.
- The feature must have a
migrations/directory.
See also
- db:upgrade. Apply pending migrations
- db:status. Show current migration status
- db:rollback. Roll back migrations
- db:reset. Drop all tables and re-apply migrations