05/02 Phase B - update migration file

This commit is contained in:
Nguyen Ngo
2026-05-02 11:49:00 -04:00
parent bad39522fa
commit d36c0d2e1e
+50 -46
View File
@@ -7,69 +7,73 @@ on the device (mobile_local_id). The server checks this field before creating
a new record so that network retries never produce duplicate rows. a new record so that network retries never produce duplicate rows.
Revision ID: phase_b_mobile_local_id Revision ID: phase_b_mobile_local_id
Revises: phase9_user_full_name Revises: phase12_performance_indexes
""" """
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
revision = 'phase_b_mobile_local_id' revision = 'phase_b_mobile_local_id'
down_revision = 'phase9_user_full_name' down_revision = 'phase12_performance_indexes'
branch_labels = None branch_labels = None
depends_on = None depends_on = None
def _column_exists(conn, table, column):
result = conn.execute(sa.text(
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS "
"WHERE TABLE_SCHEMA = DATABASE() "
"AND TABLE_NAME = :table AND COLUMN_NAME = :column"
), {"table": table, "column": column})
return result.scalar() > 0
def _index_exists(conn, table, index):
result = conn.execute(sa.text(
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS "
"WHERE TABLE_SCHEMA = DATABASE() "
"AND TABLE_NAME = :table AND INDEX_NAME = :index"
), {"table": table, "index": index})
return result.scalar() > 0
def upgrade(): def upgrade():
conn = op.get_bind()
# ── inspections.mobile_local_id ─────────────────────────────────────── # ── inspections.mobile_local_id ───────────────────────────────────────
with op.batch_alter_table('inspections') as batch_op: if not _column_exists(conn, 'inspections', 'mobile_local_id'):
# Check if column already exists (safe re-run) op.execute(sa.text(
conn = op.get_bind() "ALTER TABLE inspections ADD COLUMN mobile_local_id VARCHAR(64) NULL"
columns = [row[1] for row in conn.execute(sa.text('PRAGMA table_info(inspections)')).fetchall()] \ ))
if conn.dialect.name == 'sqlite' \
else [row['COLUMN_NAME'] for row in conn.execute(
sa.text(
"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS "
"WHERE TABLE_NAME = 'inspections' AND TABLE_SCHEMA = DATABASE()"
)
).mappings()]
if 'mobile_local_id' not in columns: if not _index_exists(conn, 'inspections', 'idx_inspections_mobile_local_id'):
batch_op.add_column( op.execute(sa.text(
sa.Column('mobile_local_id', sa.String(64), nullable=True) "CREATE INDEX idx_inspections_mobile_local_id ON inspections(mobile_local_id)"
) ))
# Index for fast idempotency lookups
op.execute(sa.text(
"CREATE INDEX IF NOT EXISTS idx_inspections_mobile_local_id "
"ON inspections(mobile_local_id)"
))
# ── issues.mobile_local_id ──────────────────────────────────────────── # ── issues.mobile_local_id ────────────────────────────────────────────
with op.batch_alter_table('issues') as batch_op: if not _column_exists(conn, 'issues', 'mobile_local_id'):
conn = op.get_bind() op.execute(sa.text(
columns = [row[1] for row in conn.execute(sa.text('PRAGMA table_info(issues)')).fetchall()] \ "ALTER TABLE issues ADD COLUMN mobile_local_id VARCHAR(64) NULL"
if conn.dialect.name == 'sqlite' \ ))
else [row['COLUMN_NAME'] for row in conn.execute(
sa.text(
"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS "
"WHERE TABLE_NAME = 'issues' AND TABLE_SCHEMA = DATABASE()"
)
).mappings()]
if 'mobile_local_id' not in columns: if not _index_exists(conn, 'issues', 'idx_issues_mobile_local_id'):
batch_op.add_column( op.execute(sa.text(
sa.Column('mobile_local_id', sa.String(64), nullable=True) "CREATE INDEX idx_issues_mobile_local_id ON issues(mobile_local_id)"
) ))
op.execute(sa.text(
"CREATE INDEX IF NOT EXISTS idx_issues_mobile_local_id "
"ON issues(mobile_local_id)"
))
def downgrade(): def downgrade():
with op.batch_alter_table('inspections') as batch_op: conn = op.get_bind()
batch_op.drop_column('mobile_local_id')
with op.batch_alter_table('issues') as batch_op: if _index_exists(conn, 'inspections', 'idx_inspections_mobile_local_id'):
batch_op.drop_column('mobile_local_id') op.execute(sa.text("DROP INDEX idx_inspections_mobile_local_id ON inspections"))
if _column_exists(conn, 'inspections', 'mobile_local_id'):
op.execute(sa.text("ALTER TABLE inspections DROP COLUMN mobile_local_id"))
if _index_exists(conn, 'issues', 'idx_issues_mobile_local_id'):
op.execute(sa.text("DROP INDEX idx_issues_mobile_local_id ON issues"))
if _column_exists(conn, 'issues', 'mobile_local_id'):
op.execute(sa.text("ALTER TABLE issues DROP COLUMN mobile_local_id"))