Fix: seed pre-tracking migrations to skip already-applied 02 and 03
Migration 02 and 03 were applied before the schema_migrations tracking table existed, so they had no record and the runner tried to re-run them, hitting non-idempotent TimescaleDB policy/trigger/cagg statements. seed_pre_tracking_migrations() checks for sentinel schema objects and inserts records for any migration that was clearly already applied: - 02: tracksolid.devices table exists - 03: position_history.altitude column exists Called immediately after ensure_tracking_table() on every startup. Safe on fresh databases (objects absent → nothing seeded → runs normally). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
63e555b822
commit
5d47eece6b
1 changed files with 40 additions and 0 deletions
|
|
@ -68,6 +68,45 @@ def ensure_tracking_table(conn):
|
|||
conn.commit()
|
||||
|
||||
|
||||
def seed_pre_tracking_migrations(conn):
|
||||
"""
|
||||
Retroactively mark migrations as applied if their schema objects already
|
||||
exist. Required when the tracking table is introduced to a database that
|
||||
was migrated before tracking existed — prevents re-running non-idempotent
|
||||
statements (TimescaleDB policies, triggers, continuous aggregates).
|
||||
"""
|
||||
seeds = []
|
||||
|
||||
with conn.cursor() as cur:
|
||||
# Migration 02: tracksolid.devices is the canonical sentinel table
|
||||
cur.execute("""
|
||||
SELECT 1 FROM information_schema.tables
|
||||
WHERE table_schema = 'tracksolid' AND table_name = 'devices'
|
||||
""")
|
||||
if cur.fetchone():
|
||||
seeds.append("02_tracksolid_full_schema_rev.sql")
|
||||
|
||||
# Migration 03: position_history.altitude column added in this migration
|
||||
cur.execute("""
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'tracksolid'
|
||||
AND table_name = 'position_history'
|
||||
AND column_name = 'altitude'
|
||||
""")
|
||||
if cur.fetchone():
|
||||
seeds.append("03_webhook_schema_migration.sql")
|
||||
|
||||
for filename in seeds:
|
||||
cur.execute("""
|
||||
INSERT INTO tracksolid.schema_migrations (filename)
|
||||
VALUES (%s) ON CONFLICT DO NOTHING
|
||||
""", (filename,))
|
||||
|
||||
conn.commit()
|
||||
if seeds:
|
||||
print(f" Seeded pre-tracking migrations as applied: {', '.join(seeds)}")
|
||||
|
||||
|
||||
def already_applied(conn, filename):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
|
|
@ -128,6 +167,7 @@ def main():
|
|||
|
||||
conn = get_conn()
|
||||
ensure_tracking_table(conn)
|
||||
seed_pre_tracking_migrations(conn)
|
||||
|
||||
applied = skipped = 0
|
||||
for sql_file in MIGRATIONS:
|
||||
|
|
|
|||
Loading…
Reference in a new issue