"""Drop unused sync columns from lab tables (server-only module). Revision ID: lab_drop_sync_columns Revises: lab_animal_profile_milk_yield Create Date: 2026-06-09 """ from __future__ import annotations import sqlalchemy as sa from alembic import op revision = "lab_drop_sync_columns" down_revision = "lab_animal_profile_milk_yield" branch_labels = None depends_on = None _LAB_TABLES = ( "lab_animal_profile", "lab_recipe_ration", "lab_ration_line", ) _CUSTOMER_DROP_TABLES = ("lab_customer_address", "lab_customer") _CUSTOMER_ID_COLUMNS = (("lab_recipe_ration", "customer_id"),) _SYNC_COLS = ("sync_timestamp", "sync_status", "content_hash") def _drop_customer_layer(insp: sa.Inspector) -> None: for table, column in _CUSTOMER_ID_COLUMNS: idx = f"ix_{table}_{column}" if table in insp.get_table_names(): op.execute(sa.text(f'DROP INDEX IF EXISTS "{idx}"')) for table, column in _CUSTOMER_ID_COLUMNS: if table not in insp.get_table_names(): continue cols = {c["name"] for c in insp.get_columns(table)} if column in cols: with op.batch_alter_table(table) as batch: batch.drop_column(column) for table in _CUSTOMER_DROP_TABLES: if table in insp.get_table_names(): op.drop_table(table) def upgrade(**kw) -> None: if kw.get("tag") == "reports": return bind = op.get_bind() insp = sa.inspect(bind) _drop_customer_layer(insp) insp = sa.inspect(bind) for table in _LAB_TABLES: if table not in insp.get_table_names(): continue cols = {c["name"] for c in insp.get_columns(table)} drop = [c for c in _SYNC_COLS if c in cols] if not drop: continue with op.batch_alter_table(table) as batch: for col in drop: batch.drop_column(col) def downgrade(**kw) -> None: if kw.get("tag") == "reports": return bind = op.get_bind() insp = sa.inspect(bind) for table in _LAB_TABLES: if table not in insp.get_table_names(): continue cols = {c["name"] for c in insp.get_columns(table)} with op.batch_alter_table(table) as batch: if "sync_timestamp" not in cols: batch.add_column(sa.Column("sync_timestamp", sa.DateTime(), nullable=True)) if "sync_status" not in cols: batch.add_column( sa.Column("sync_status", sa.String(length=20), nullable=False, server_default="pending") ) if "content_hash" not in cols: batch.add_column( sa.Column("content_hash", sa.String(length=64), nullable=False, server_default="") )