Extend seed sentinels to cover migrations 04 and 05
Containers share one DB — when ingest_movement applies 04, ingest_events and webhook_receiver start later and find distance_m already renamed, causing a spurious FATAL before the next restart catches the recorded row. Added sentinels for all four migrations so any container self-heals on first startup regardless of which container ran first: 04 — trips.distance_km column exists 05 — tracksolid.device_events table exists Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5d47eece6b
commit
5f1b32f1dc
1 changed files with 45 additions and 28 deletions
|
|
@ -71,40 +71,57 @@ def ensure_tracking_table(conn):
|
||||||
def seed_pre_tracking_migrations(conn):
|
def seed_pre_tracking_migrations(conn):
|
||||||
"""
|
"""
|
||||||
Retroactively mark migrations as applied if their schema objects already
|
Retroactively mark migrations as applied if their schema objects already
|
||||||
exist. Required when the tracking table is introduced to a database that
|
exist. Checked on every startup — safe to run repeatedly (ON CONFLICT DO
|
||||||
was migrated before tracking existed — prevents re-running non-idempotent
|
NOTHING). Prevents re-running non-idempotent statements when a second
|
||||||
statements (TimescaleDB policies, triggers, continuous aggregates).
|
container starts after another has already applied the migration, or when
|
||||||
|
the tracking table is introduced to a database migrated before it existed.
|
||||||
|
|
||||||
|
Sentinel objects per migration:
|
||||||
|
02 — tracksolid.devices table exists
|
||||||
|
03 — position_history.altitude column exists
|
||||||
|
04 — trips.distance_km column exists (renamed from distance_m)
|
||||||
|
05 — tracksolid.device_events table exists (new in 05)
|
||||||
"""
|
"""
|
||||||
|
checks = [
|
||||||
|
(
|
||||||
|
"02_tracksolid_full_schema_rev.sql",
|
||||||
|
"SELECT 1 FROM information_schema.tables "
|
||||||
|
"WHERE table_schema='tracksolid' AND table_name='devices'",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"03_webhook_schema_migration.sql",
|
||||||
|
"SELECT 1 FROM information_schema.columns "
|
||||||
|
"WHERE table_schema='tracksolid' AND table_name='position_history' "
|
||||||
|
"AND column_name='altitude'",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"04_bug_fix_migration.sql",
|
||||||
|
"SELECT 1 FROM information_schema.columns "
|
||||||
|
"WHERE table_schema='tracksolid' AND table_name='trips' "
|
||||||
|
"AND column_name='distance_km'",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"05_enhancement_migration.sql",
|
||||||
|
"SELECT 1 FROM information_schema.tables "
|
||||||
|
"WHERE table_schema='tracksolid' AND table_name='device_events'",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
seeds = []
|
seeds = []
|
||||||
|
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
# Migration 02: tracksolid.devices is the canonical sentinel table
|
for filename, query in checks:
|
||||||
cur.execute("""
|
cur.execute(query)
|
||||||
SELECT 1 FROM information_schema.tables
|
|
||||||
WHERE table_schema = 'tracksolid' AND table_name = 'devices'
|
|
||||||
""")
|
|
||||||
if cur.fetchone():
|
if cur.fetchone():
|
||||||
seeds.append("02_tracksolid_full_schema_rev.sql")
|
cur.execute(
|
||||||
|
"INSERT INTO tracksolid.schema_migrations (filename) "
|
||||||
# Migration 03: position_history.altitude column added in this migration
|
"VALUES (%s) ON CONFLICT DO NOTHING",
|
||||||
cur.execute("""
|
(filename,),
|
||||||
SELECT 1 FROM information_schema.columns
|
)
|
||||||
WHERE table_schema = 'tracksolid'
|
seeds.append(filename)
|
||||||
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()
|
conn.commit()
|
||||||
if seeds:
|
if seeds:
|
||||||
print(f" Seeded pre-tracking migrations as applied: {', '.join(seeds)}")
|
print(f" Seeded as applied: {', '.join(seeds)}")
|
||||||
|
|
||||||
|
|
||||||
def already_applied(conn, filename):
|
def already_applied(conn, filename):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue