Workflows and commands for managing Alembic database migrations and schema changes in the letta-cloud core app, including using uv, just, LETTA_PG_URI, and switching between SQLite and Postgres.
Use this skill whenever you need to change the database schema or debug Alembic
migrations in apps/core of the letta-cloud repo.
This skill assumes:
apps/coreapps/core/alembicuvjust ready for environment + DB setupjust readyexport LETTA_PG_URI=postgresql+pg8000://postgres:postgres@localhost:5432/letta-coreuv run alembic revision --autogenerate -m "<short_message>"uv run alembic upgrade headSee references/migration-commands.md for exact commands and variants.
letta/orm/...:
ProjectMixin) when available instead of
duplicating columns.just ready if dependencies or environment may have changed.LETTA_PG_URI is set if you want the migration to target Postgres.uv.alembic/versions/:
op.add_column / op.alter_column match expectations.uv run alembic upgrade head.Use this pattern for changes like adding project_id columns via ProjectMixin.
upgrade() that:
op.get_bind() and SQLAlchemy Core/SQL to backfill data.downgrade() simple and safe (ideally reversible).LETTA_PG_URI set, using uv run alembic upgrade head.Typical cases:
Workflow:
alembic/versions/.LETTA_PG_URI and re-running upgrade.See references/sqlite-vs-postgres-gotchas.md for SQLite-specific issues.
Alembic picks the engine based on letta.settings.DatabaseChoice and
environment variables.
General rules:
just ready handles baseline migrations.LETTA_PG_URI.Workflow for Postgres-targeted migration:
export LETTA_PG_URI=postgresql+pg8000://postgres:postgres@localhost:5432/letta-coreapps/core:
uv run alembic upgrade headuv run alembic revision --autogenerate -m "..."If your local Postgres database has drifted from main (e.g., applied migrations that no longer exist, or has stale schema), you can reset it to generate a clean migration.
From the repo root (/Users/sarahwooders/repos/letta-cloud):
# 1. Remove postgres data directory
rm -rf ./data/postgres
# 2. Stop the running postgres container
docker stop $(docker ps -q --filter ancestor=ankane/pgvector)
# 3. Restart services (creates fresh postgres)
just start-services
# 4. Wait a moment for postgres to be ready, then apply all migrations
cd apps/core
export LETTA_PG_URI=postgresql+pg8000://postgres:postgres@localhost:5432/letta-core
uv run alembic upgrade head
# 5. Now generate your new migration
uv run alembic revision --autogenerate -m "your migration message"
This ensures the migration is generated against a clean database state matching main, avoiding spurious diffs from local-only schema changes.
uv run alembic upgrade head (with appropriate engine/URI).LETTA_PG_URI and rerun.Base.metadata) are correct and that the
changed model is imported in Alembic env context.references/migration-commands.md — canonical commands for uv, Alembic,
and just.references/sqlite-vs-postgres-gotchas.md — engine-specific pitfalls and
how to avoid them.