Changing the Database Schema
Database Setup covers the very first alembic upgrade head against an empty database. This is the loop you’ll actually use — every time a model changes.
1. Change the model
Section titled “1. Change the model”Edit app/models.py directly. Item already has a created_at field, defined like this — any new timestamp field you add follows the same shape:
class Item(ItemBase, table=True): created_at: datetime | None = Field( default_factory=get_datetime_utc, sa_type=DateTime(timezone=True), )2. Generate the migration
Section titled “2. Generate the migration”cd backenduv run alembic revision --autogenerate -m "add created_at to item"Alembic diffs your models against the database’s current state — app/alembic/env.py points it at SQLModel.metadata — and writes a new file into app/alembic/versions/. A real one looks like this:
def upgrade(): op.add_column('item', sa.Column('created_at', sa.DateTime(timezone=True), nullable=True))
def downgrade(): op.drop_column('item', 'created_at')3. Read it before applying it
Section titled “3. Read it before applying it”Autogenerate is a diff, not a decision-maker — it gets a few things wrong in predictable ways:
4. Apply it
Section titled “4. Apply it”uv run alembic upgrade headUndoing one
Section titled “Undoing one”uv run alembic downgrade -1downgrade() is autogenerated too, alongside upgrade() — the same review applies to both before you rely on it.