fix: Make migration idempotent - check if columns exist before adding

This commit is contained in:
Claude committed 2025-11-24 08:17:49 +00:00
1 parent 30861acdb8
commit 2384fca9ca
1 file changed
+45 -25
@@ -1,7 +1,7 @@
"""Add missing columns to search_sites table """Add missing columns to search_sites table
Revision ID: add_search_sites_columns Revision ID: add_search_sites_columns
Revises: merge_heads Revises: add_notification_channels
Create Date: 2025-11-24 Create Date: 2025-11-24
""" """
@@ -9,6 +9,7 @@ from collections.abc import Sequence
import sqlalchemy as sa import sqlalchemy as sa
from alembic import op from alembic import op
from sqlalchemy import inspect
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision: str = "add_search_sites_columns" revision: str = "add_search_sites_columns"
@@ -17,33 +18,52 @@ branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None
def column_exists(table_name: str, column_name: str) -> bool:
"""Check if a column exists in a table."""
bind = op.get_bind()
inspector = inspect(bind)
columns = [col["name"] for col in inspector.get_columns(table_name)]
return column_name in columns
def upgrade() -> None: def upgrade() -> None:
"""Add debug_enabled, price_selector, search_url, product_link_selector columns to search_sites.""" """Add debug_enabled, price_selector, search_url, product_link_selector columns to search_sites."""
# Add debug_enabled column # Add debug_enabled column (only if not exists)
op.add_column( if not column_exists("search_sites", "debug_enabled"):
"search_sites", op.add_column(
sa.Column("debug_enabled", sa.Boolean(), server_default="false", nullable=False), "search_sites",
) sa.Column("debug_enabled", sa.Boolean(), server_default="false", nullable=False),
# Add price_selector column )
op.add_column(
"search_sites", # Add price_selector column (only if not exists)
sa.Column("price_selector", sa.String(), nullable=True), if not column_exists("search_sites", "price_selector"):
) op.add_column(
# Add search_url column "search_sites",
op.add_column( sa.Column("price_selector", sa.String(), nullable=True),
"search_sites", )
sa.Column("search_url", sa.String(), nullable=True),
) # Add search_url column (only if not exists)
# Add product_link_selector column if not column_exists("search_sites", "search_url"):
op.add_column( op.add_column(
"search_sites", "search_sites",
sa.Column("product_link_selector", sa.String(), nullable=True), sa.Column("search_url", sa.String(), nullable=True),
) )
# Add product_link_selector column (only if not exists)
if not column_exists("search_sites", "product_link_selector"):
op.add_column(
"search_sites",
sa.Column("product_link_selector", sa.String(), nullable=True),
)
def downgrade() -> None: def downgrade() -> None:
"""Remove added columns from search_sites.""" """Remove added columns from search_sites."""
op.drop_column("search_sites", "product_link_selector") if column_exists("search_sites", "product_link_selector"):
op.drop_column("search_sites", "search_url") op.drop_column("search_sites", "product_link_selector")
op.drop_column("search_sites", "price_selector") if column_exists("search_sites", "search_url"):
op.drop_column("search_sites", "debug_enabled") op.drop_column("search_sites", "search_url")
if column_exists("search_sites", "price_selector"):
op.drop_column("search_sites", "price_selector")
if column_exists("search_sites", "debug_enabled"):
op.drop_column("search_sites", "debug_enabled")