Skip to content

fix(migrations): make f061 idempotent so fresh deployments can migrate - #848

Open
libingtong wants to merge 1 commit into
dataelement:mainfrom
libingtong:fix/f061-idempotent-migration
Open

fix(migrations): make f061 idempotent so fresh deployments can migrate#848
libingtong wants to merge 1 commit into
dataelement:mainfrom
libingtong:fix/f061-idempotent-migration

Conversation

@libingtong

Copy link
Copy Markdown

001_initial_schema.py builds the schema with Base.metadata.create_all(), so a freshly provisioned database already has enterprise_info.tenant_id — the model declares it. f061 then calls op.add_column() unconditionally and fails:

asyncpg.exceptions.DuplicateColumnError:
column "tenant_id" of relation "enterprise_info" already exists

alembic upgrade head therefore cannot complete on any fresh deployment, and backend/entrypoint.sh aborts before starting uvicorn since it runs migrations first.

Reproduction

Against an empty database, on a clean checkout of main:

docker run -d --name pg -e POSTGRES_USER=clawith -e POSTGRES_PASSWORD=clawith \
  -e POSTGRES_DB=clawith -p 5432:5432 postgres:15-alpine
cd backend
DATABASE_URL=postgresql+asyncpg://clawith:clawith@127.0.0.1:5432/clawith \
  alembic upgrade head

This PR

Guards the DDL with IF NOT EXISTS / IF EXISTS, matching the convention already used throughout 010_column_modify.py. This also makes the module docstring's stated "Idempotence: Safe for retry" property actually hold.

Existing deployments that predate the column are unaffected — the column is still created there.

Verified

Both paths tested:

  • fresh database → alembic upgrade head now completes
  • existing database at allow_checkpoint_deliveries → upgrades through f060 to f061 with data intact

Also drops two imports that are no longer referenced.

001_initial_schema.py builds the schema with Base.metadata.create_all(), so a
freshly provisioned database already has enterprise_info.tenant_id — the model
declares it. f061 then calls op.add_column() unconditionally and fails:

    asyncpg.exceptions.DuplicateColumnError:
    column "tenant_id" of relation "enterprise_info" already exists

`alembic upgrade head` therefore cannot complete on any fresh deployment, and
backend/entrypoint.sh aborts before starting uvicorn (it runs migrations first).

Reproduce against an empty database:

    docker run -d --name pg -e POSTGRES_USER=clawith -e POSTGRES_PASSWORD=clawith \
      -e POSTGRES_DB=clawith -p 5432:5432 postgres:15-alpine
    cd backend
    DATABASE_URL=postgresql+asyncpg://clawith:clawith@127.0.0.1:5432/clawith \
      alembic upgrade head

Guard the DDL with IF NOT EXISTS / IF EXISTS, matching the convention already
used in 010_column_modify.py. This also makes the module docstring's stated
"Idempotence: Safe for retry" property actually hold.

Existing deployments that predate the column are unaffected — the column is
still created there. Verified both paths: fresh database, and an existing
database at allow_checkpoint_deliveries upgrading through f060 to f061.

Drops two imports that are no longer referenced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant