Conversation
Contributor
|
👋 This PR needs a couple of things fixed before OpenHands can review it:
Push an update once this is addressed and this check re-runs automatically. This is an automated check - no AI was used to generate this comment. |
added 2 commits
September 13, 2026 07:58
`AUTOMATION_DB_URL=postgresql+asyncpg://...` is the documented way to point a self-hosted deployment at Postgres, but `migrations/env.py` handed that URL straight to the sync `create_engine()`, so `alembic upgrade head` failed with `sqlalchemy.exc.MissingGreenlet`. Only the `sqlite+aiosqlite` prefix was rewritten to a sync driver. Generalize the helper into `normalize_url_for_alembic()`, which also maps `postgresql+asyncpg` to `postgresql+pg8000` — already a dependency, and already the driver `env.py` uses for its host/port path — and apply it everywhere a configured URL reaches alembic. A URL-configured Postgres engine now gets the same `AUTOMATION_DB_SSL_MODE` connect args as the host/port path. Claude-Session: https://claude.ai/code/session_01T5LhMv1aKbckQ6SLd4sPGZ
A self-hosted Postgres deployment had no way to get its schema created: the lifespan ran `alembic upgrade head` only when the engine was SQLite, so a fresh `AUTOMATION_DB_URL=postgresql+asyncpg://...` deployment logged `UndefinedTableError` until somebody ran alembic by hand. Add `AUTOMATION_AUTO_MIGRATE`. Unset keeps today's behaviour — SQLite migrates on startup, Postgres does not — so Cloud, which migrates from its own deploy pipeline, is unaffected. `true` also migrates Postgres; `false` disables startup migrations entirely. Concurrent pods are already safe: `migrations/env.py` takes `pg_advisory_lock(MIGRATION_LOCK_ID)` for Postgres. Claude-Session: https://claude.ai/code/session_01T5LhMv1aKbckQ6SLd4sPGZ
lkshrk
force-pushed
the
feat/postgres-auto-migrate
branch
from
September 13, 2026 06:00
a22a358 to
3aaa792
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
HUMAN:
Self-hosted deployment on Kubernetes with CloudNativePG Postgres; today I run alembic from a separate Job before the pod starts. Ran
tests/test_startup_migrations.py,tests/test_config.pyand pre-commit locally on this branch. Stacked on #420.AGENT:
Problem
The lifespan runs
alembic upgrade headonly when the engine is SQLite:A self-hosted deployment that sets
AUTOMATION_DB_URL=postgresql+asyncpg://…therefore starts against an empty database and never creates its schema. Every
scheduler and dispatcher tick logs
UndefinedTableErroruntil somebody runsalembic by hand, and nothing in the service says that is what is required.
Cloud runs its migrations from a separate deploy pipeline, so this cannot simply
be switched on for Postgres — it has to be opt-in.
Fix
A new
ServiceSettingsfield,auto_migrate(AUTOMATION_AUTO_MIGRATE), withthree states:
truefalseEverything else in that block is unchanged: the same migrations-directory
discovery, the same
alembic.config.Config, the same failure handling. Only thetwo log messages lost their now-inaccurate "SQLite" qualifier.
Concurrent startup is already safe.
migrations/env.pytakespg_advisory_lock(MIGRATION_LOCK_ID)for Postgres and releases it in afinally, so several pods coming up at once serialize on the lock rather thanracing.
Default off for Postgres means Cloud is untouched — its
AUTOMATION_AUTO_MIGRATEis unset, so the gate evaluates to
engine_result.is_sqlite, which isFalse.Verification
tests/test_startup_migrations.pydrives the real lifespan with a stubbedengine, stubbed background loops and a mocked
alembic.command.upgrade, andcovers all five combinations: Postgres unset /
true/falseand SQLiteunset /
false. The opted-in Postgres case also asserts the alembic configreceives the sync
postgresql+pg8000://URL.if engine_result.is_sqlite:fails two of those five,so the tests are not vacuous.
tests/test_config.pycovers the unset default andtrue/1/false/0parsing of
AUTOMATION_AUTO_MIGRATE.pre-commit(ruff format, ruff lint, pycodestyle, pyright) clean on thechanged files.
Docs
The
AGENTS.md"Database" table now records the Postgres option and the SQLiteopt-out.