Skip to content

Commit b878ae2

Browse files
author
Olivier Gintrand
committed
alembic: make user_gateway_credentials migration idempotent
Check if table/indexes already exist before creating. Prevents DuplicateTable error when upgrading from RC2 which created the same schema under different revision IDs.
1 parent 4cfdb10 commit b878ae2

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

mcpgateway/alembic/versions/a1b2c3d4e5f6_add_user_gateway_credentials_table.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# Third-Party
1111
from alembic import op
1212
import sqlalchemy as sa
13+
from sqlalchemy import inspect
1314

1415
# revision identifiers, used by Alembic.
1516
revision = "a1b2c3d4e5f6"
@@ -19,20 +20,29 @@
1920

2021

2122
def upgrade() -> None:
22-
op.create_table(
23-
"user_gateway_credentials",
24-
sa.Column("id", sa.String(36), primary_key=True),
25-
sa.Column("gateway_id", sa.String(36), sa.ForeignKey("gateways.id", ondelete="CASCADE"), nullable=False),
26-
sa.Column("app_user_email", sa.String(255), sa.ForeignKey("email_users.email", ondelete="CASCADE"), nullable=False),
27-
sa.Column("credential_type", sa.String(50), nullable=False),
28-
sa.Column("credential_value", sa.Text(), nullable=False),
29-
sa.Column("label", sa.String(255), nullable=True),
30-
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
31-
sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), onupdate=sa.func.now()),
32-
sa.UniqueConstraint("gateway_id", "app_user_email", name="uq_credential_gateway_user"),
33-
)
34-
op.create_index("idx_user_credentials_gateway", "user_gateway_credentials", ["gateway_id"])
35-
op.create_index("idx_user_credentials_email", "user_gateway_credentials", ["app_user_email"])
23+
conn = op.get_bind()
24+
inspector = inspect(conn)
25+
existing_tables = inspector.get_table_names()
26+
27+
if "user_gateway_credentials" not in existing_tables:
28+
op.create_table(
29+
"user_gateway_credentials",
30+
sa.Column("id", sa.String(36), primary_key=True),
31+
sa.Column("gateway_id", sa.String(36), sa.ForeignKey("gateways.id", ondelete="CASCADE"), nullable=False),
32+
sa.Column("app_user_email", sa.String(255), sa.ForeignKey("email_users.email", ondelete="CASCADE"), nullable=False),
33+
sa.Column("credential_type", sa.String(50), nullable=False),
34+
sa.Column("credential_value", sa.Text(), nullable=False),
35+
sa.Column("label", sa.String(255), nullable=True),
36+
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
37+
sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), onupdate=sa.func.now()),
38+
sa.UniqueConstraint("gateway_id", "app_user_email", name="uq_credential_gateway_user"),
39+
)
40+
41+
existing_indexes = {idx["name"] for idx in inspector.get_indexes("user_gateway_credentials")}
42+
if "idx_user_credentials_gateway" not in existing_indexes:
43+
op.create_index("idx_user_credentials_gateway", "user_gateway_credentials", ["gateway_id"])
44+
if "idx_user_credentials_email" not in existing_indexes:
45+
op.create_index("idx_user_credentials_email", "user_gateway_credentials", ["app_user_email"])
3646

3747

3848
def downgrade() -> None:

0 commit comments

Comments
 (0)