diff --git a/.last-branch b/.last-branch index 4c130c6..76e3ecb 100644 --- a/.last-branch +++ b/.last-branch @@ -1 +1 @@ -v20260115-13-autotask-runchecks-create-ticket +v20260115-14-autotask-runchecks-ticket-migration-fix diff --git a/containers/backupchecks/src/backend/app/migrations.py b/containers/backupchecks/src/backend/app/migrations.py index 03e2eea..f7708dc 100644 --- a/containers/backupchecks/src/backend/app/migrations.py +++ b/containers/backupchecks/src/backend/app/migrations.py @@ -3,6 +3,31 @@ from sqlalchemy import inspect, text from .database import db +def _get_table_columns(conn, table_name: str) -> set[str]: + """Return a set of column names for a table using the provided connection. + + Returns an empty set when the table does not exist or cannot be inspected. + + Using information_schema keeps this helper stable across SQLAlchemy + versions and avoids creating nested connections while inside begin() blocks. + """ + + try: + result = conn.execute( + text( + """ + SELECT column_name + FROM information_schema.columns + WHERE table_name = :table + """ + ), + {"table": table_name}, + ) + return {row[0] for row in result.fetchall()} + except Exception: + return set() + + def _column_exists(table_name: str, column_name: str) -> bool: """Return True if the given column exists on the given table.""" engine = db.get_engine() @@ -923,9 +948,10 @@ def migrate_job_runs_autotask_ticket_fields() -> None: return try: - with engine.connect() as conn: + with engine.begin() as conn: cols = _get_table_columns(conn, table) if not cols: + print("[migrations] job_runs table not found; skipping migrate_job_runs_autotask_ticket_fields") return if "autotask_ticket_id" not in cols: @@ -955,12 +981,14 @@ def migrate_job_runs_autotask_ticket_fields() -> None: ) except Exception as exc: print( - f"[migrations] Could not add FK job_runs.autotask_ticket_created_by_user_id -> users.id (continuing): {exc}" + f"[migrations] Could not add FK job_runs_autotask_ticket_created_by_user_id -> users.id (continuing): {exc}" ) - conn.execute(text('CREATE INDEX IF NOT EXISTS idx_job_runs_autotask_ticket_id ON "job_runs" (autotask_ticket_id)')) + conn.execute( + text('CREATE INDEX IF NOT EXISTS idx_job_runs_autotask_ticket_id ON "job_runs" (autotask_ticket_id)') + ) except Exception as exc: - print(f"[migrations] job_runs table not found; skipping migrate_job_runs_autotask_ticket_fields: {exc}") + print(f"[migrations] migrate_job_runs_autotask_ticket_fields failed (continuing): {exc}") return print("[migrations] migrate_job_runs_autotask_ticket_fields completed.") diff --git a/docs/changelog.md b/docs/changelog.md index 454b22e..7ebe7ae 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -100,6 +100,13 @@ Changes: - Implemented a new backend endpoint to refresh mapping status for all customers with an Autotask Company ID and return a status summary (ok/renamed/missing/invalid). - Updated the Customers UI to call the refresh-all endpoint, show a short result summary, and reload to reflect updated mapping states. +## v20260115-14-autotask-runchecks-ticket-migration-fix + +- Fixed missing database helper used by the Autotask ticket fields migration for job runs. +- Corrected the job_runs migration to ensure Autotask ticket columns are created reliably and committed properly. +- Resolved Run Checks errors caused by incomplete database migrations after introducing Autotask ticket support. + + *** ## v0.1.21