Command Line Tool¶
Advanced Alchemy provides a command-line interface (CLI) for common database operations and project management tasks.
Installation¶
The CLI is installed with Advanced Alchemy with the extra cli:
Basic Usage¶
The CLI can be invoked using the alchemy command:
alchemy --help
Global Options¶
The following options are available for all commands:
Option |
Explanation |
|---|---|
|
Required. Dotted path to SQLAlchemy config(s), it’s an instance of |
|
Optional. Specify which SQLAlchemy config to use |
|
Optional. Skip confirmation prompts |
|
Optional. Enable verbose output |
Config¶
Here is an example of what config looks like.
If the file is named alchemy-config.py, you would need to use it like this --config path.to.alchemy-config.config
from advanced_alchemy.config import SQLAlchemySyncConfig
# Create a test config using SQLite
config = SQLAlchemySyncConfig(
connection_string="sqlite:///test.db"
)
Available Commands¶
Migration Commands¶
These commands manage database migrations and revisions.
show-current-revision¶
Show the current revision of the database:
alchemy show-current-revision --config path.to.alchemy-config.config
Option |
Explanation |
|---|---|
|
Display detailed revision information |
downgrade¶
Downgrade database to a specific revision:
alchemy downgrade --config path.to.alchemy-config.config [REVISION]
Option |
Explanation |
|---|---|
|
Generate SQL output for offline migrations |
|
Arbitrary tag for custom env.py scripts |
|
Target revision (default: “-1”) |
upgrade¶
Upgrade database to a specific revision:
alchemy upgrade --config path.to.alchemy-config.config [REVISION]
Option |
Explanation |
|---|---|
|
Generate SQL output for offline migrations |
|
Arbitrary tag for custom env.py scripts |
|
Target revision (default: “head”) |
stamp¶
Stamp the revision table with a specific revision without running migrations:
alchemy stamp --config path.to.alchemy-config.config REVISION
Option |
Explanation |
|---|---|
|
Generate SQL output for offline migrations |
|
Arbitrary tag for custom env.py scripts |
|
Delete all entries in version table before stamping |
|
Target revision to stamp (required) |
Use cases:
Initialize version table for existing database
Mark migrations as applied without running them
Reset migration history (with
--purge)Generate SQL for manual database stamping (with
--sql)
init¶
Initialize migrations for the project:
alchemy init --config path.to.alchemy-config.config [DIRECTORY]
Option |
Explanation |
|---|---|
|
Support multiple databases |
|
Create __init__.py for created folder (default: True) |
|
Directory for migration files (optional) |
make-migrations¶
Create a new migration revision:
alchemy make-migrations --config path.to.alchemy-config.config
Option |
Explanation |
|---|---|
|
Revision message |
|
Automatically detect changes (default: True) |
|
Export to .sql instead of writing to database |
|
Base revision for new revision (default: “head”) |
|
Allow non-head revision as the “head” |
|
Branch label for new revision |
|
Specific path for version file |
|
Specific revision ID |
Note
PostgreSQL enum changes
Alembic’s autogenerate does not detect changes to PostgreSQL native ENUM
types on its own (for example, adding a value to an existing StrEnum).
Advanced Alchemy’s migration templates automatically enable this detection
when the optional alembic-postgresql-enum package is installed.
Install it with the postgresql extra:
pip install "advanced-alchemy[postgresql]"
The generated env.py imports the package inside a try/except block,
so no configuration is required — it activates only when the package is present.
If you initialized your migrations with an older version of Advanced Alchemy,
add import alembic_postgresql_enum near the top of your env.py to enable it.
Inspection Commands¶
These commands inspect migration history and database state.
check¶
Check if the database is up to date with the current migration revision:
alchemy check --config path.to.alchemy-config.config
Returns exit code 0 if database is current, non-zero otherwise.
Use cases:
CI/CD validation before deployment
Pre-deployment smoke tests
Health checks
heads¶
Show current available heads in the migration script directory:
alchemy heads --config path.to.alchemy-config.config
Option |
Explanation |
|---|---|
|
Display detailed head information |
|
Resolve dependencies between heads |
Use cases:
Detect multiple heads (branch conflicts)
Verify migration graph state
Branch development coordination
history¶
List migration changesets in chronological order:
alchemy history --config path.to.alchemy-config.config
Option |
Explanation |
|---|---|
|
Display detailed revision information |
|
Revision range to display (e.g., ‘base:head’, ‘abc:def’) |
|
Indicate the current revision in output |
Use cases:
Audit migration history
Generate migration documentation
Review changes between revisions
show¶
Show details of a specific revision:
alchemy show --config path.to.alchemy-config.config REVISION
Examples:
# Show head revision
alchemy show head --config path.to.alchemy-config.config
# Show specific revision
alchemy show abc123def --config path.to.alchemy-config.config
# Show base revision
alchemy show base --config path.to.alchemy-config.config
branches¶
Show current branch points in the migration history:
alchemy branches --config path.to.alchemy-config.config
Option |
Explanation |
|---|---|
|
Display detailed branch information |
Use cases:
Identify branch points in migration graph
Multi-team development coordination
Branch-based development workflows
Branch Management Commands¶
These commands manage branched migration workflows.
merge¶
Merge two revisions together, creating a new migration file:
alchemy merge --config path.to.alchemy-config.config REVISIONS
Option |
Explanation |
|---|---|
|
Merge message |
|
Branch label for merge revision |
|
Specify custom revision ID |
|
Revisions to merge (e.g., ‘abc123+def456’ or ‘heads’) |
Examples:
# Merge all heads
alchemy merge heads -m "merge feature branches" --config path.to.alchemy-config.config
# Merge specific revisions
alchemy merge abc123+def456 -m "merge database changes" --config path.to.alchemy-config.config
Use cases:
Resolve multiple heads (branch conflicts)
Consolidate parallel development branches
Team coordination for database changes
Utility Commands¶
These commands provide additional migration utilities.
edit¶
Edit a revision file using the system editor (set via $EDITOR environment variable):
alchemy edit --config path.to.alchemy-config.config REVISION
Examples:
# Edit latest revision
alchemy edit head --config path.to.alchemy-config.config
# Edit specific revision
alchemy edit abc123def --config path.to.alchemy-config.config
ensure-version¶
Create the Alembic version table if it doesn’t exist:
alchemy ensure-version --config path.to.alchemy-config.config
Option |
Explanation |
|---|---|
|
Generate SQL output instead of executing |
Use cases:
Database initialization workflows
Manual database setup
Generate SQL for DBA review (with
--sql)
list-templates¶
List available Alembic migration templates:
alchemy list-templates --config path.to.alchemy-config.config
Use cases:
Discover available templates for
initcommandTemplate selection for new projects
Database Commands¶
These commands manage database tables and data.
drop-all¶
Drop all tables from the database:
alchemy drop-all --config path.to.alchemy-config.config
Warning
This command is destructive and will delete all data. Use with caution.
dump-data¶
Dump specified tables from the database to JSON files:
alchemy dump-data --config path.to.alchemy-config.config --table TABLE_NAME
Option |
Explanation |
|---|---|
|
Name of table to dump (use ‘*’ for all tables) |
|
Directory to save JSON files (default: ./fixtures) |
Extending the CLI¶
If you’re using Click in your project, you can extend Advanced Alchemy’s CLI with your own commands. The CLI provides two main functions for integration:
get_alchemy_group(): Get the base CLI groupadd_migration_commands(): Add migration-related commands to a group
Basic Extension¶
Here’s how to extend the CLI with your own commands:
from advanced_alchemy.cli import get_alchemy_group, add_migration_commands
import click
# Get the base group
alchemy_group = get_alchemy_group()
# Add your custom commands
@alchemy_group.command(name="my-command")
@click.option("--my-option", help="Custom option")
def my_command(my_option):
"""My custom command."""
click.echo(f"Running my command with option: {my_option}")
# Add migration commands to your group
add_migration_commands(alchemy_group)
Custom Group Integration¶
You can also integrate Advanced Alchemy’s commands into your existing Click group:
import click
from advanced_alchemy.cli import add_migration_commands
@click.group()
def cli():
"""My application CLI."""
pass
# Add migration commands to your CLI group
add_migration_commands(cli)
@cli.command()
def my_command():
"""Custom command in your CLI."""
pass
if __name__ == "__main__":
cli()
Typer integration¶
You can integrate Advanced Alchemy’s CLI commands into your existing Typer application. Here’s how:
import typer
from advanced_alchemy.cli import get_alchemy_group, add_migration_commands
app = typer.Typer()
@app.command()
def hello(name: str) -> None:
"""Says hello to the world."""
typer.echo(f"Hello {name}")
@app.callback()
def callback():
"""
Typer app, including Click subapp
"""
pass
def create_cli() -> typer.Typer:
"""Create the CLI application with both Typer and Click commands."""
# Get the Click group from advanced_alchemy
alchemy_group = get_alchemy_group()
# Convert our Typer app to a Click command object
typer_click_object = typer.main.get_command(app)
# Add all migration commands from the alchemy group to our CLI
typer_click_object.add_command(add_migration_commands(alchemy_group))
return typer_click_object
if __name__ == "__main__":
cli = create_cli()
cli()
After setting up the integration, you can use both your Typer commands and Advanced Alchemy commands:
# Use your Typer commands
python cli.py hello Cody
# Use Advanced Alchemy commands
python cli.py alchemy upgrade --config path.to.config
python cli.py alchemy make-migrations --config path.to.config