First Steps¶
This walkthrough is the foundation of the dbwarden workflow.
The goal is not just to run commands, but to understand why each step exists and how it fits the migration lifecycle.
Step 1: Initialize the project¶
This creates:
- a migrations directory structure
- a declarative Python configuration scaffold (
dbwarden.py)
Why it matters: dbwarden expects a project-local migration layout and config source so migration behavior is deterministic per repository.
Step 2: Define one explicit database entry¶
from dbwarden import DbwardenDatabase
class Primary(DbwardenDatabase):
database_name = "primary"
default = True
database_type = "postgresql"
database_url_sync = "postgresql://user:password@localhost:5432/main"
model_paths = ["app.models"]
model_tables = ["users"]
Why it matters: dbwarden resolves migration targets from explicit typed entries, not inferred environment state. The equivalent database_config(...) function API remains supported and may appear in plugin integrations.
Step 3: Add SQLAlchemy models¶
dbwarden uses model metadata to generate migration SQL. A minimal model example:
from sqlalchemy import DateTime, Integer, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from datetime import datetime
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
Why it matters: model metadata is the input to make-migrations.
Step 4: Generate migration SQL¶
dbwarden creates a versioned SQL file under migrations/primary/.
Why it matters: this file is now part of your code review process and deployment artifact.
Step 5: Review the generated migration¶
Open the file and validate both sections:
Why it matters: rollback quality determines recovery quality.
Step 6: Apply migrations¶
During execution dbwarden:
- resolves config and target database
- acquires migration lock
- executes pending SQL
- stores migration record and checksum
- releases lock
Step 7: Verify the result¶
Use status to confirm pending/applied counts and history to confirm execution order.
Common first-run issues¶
No configuration found: ensure your project has one discovered config source with a concreteDbwardenDatabasesubclass or adatabase_config(...)callDatabase '<name>' not found: ensure--databasematches configureddatabase_nameNo SQLAlchemy models found: setmodel_pathsexplicitly in config