tracksolid_timescale_grafan.../run_migrations.py

67 lines
1.7 KiB
Python
Raw Normal View History

"""
run_migrations.py Idempotent SQL migration runner for Docker init service.
Executes each .sql migration file in order using psycopg2.
Tolerates re-run errors (e.g. "policy already exists") so deploys are safe.
"""
import os
import sys
import psycopg2
DATABASE_URL = os.environ["DATABASE_URL"]
MIGRATIONS = [
"02_tracksolid_full_schema_rev.sql",
"03_webhook_schema_migration.sql",
]
def run_file(conn, path, filename):
"""Execute a SQL file. Returns True on success, False on error."""
with open(path) as f:
sql = f.read()
try:
with conn.cursor() as cur:
cur.execute(sql)
print(f" OK: {filename}")
return True
except psycopg2.Error as e:
msg = (e.pgerror or str(e)).strip().split("\n")[0]
print(f" WARN: {filename}: {msg}")
# Connection is now in error state — must reset
conn.close()
return False
def main():
print("=== Database Migration Runner ===")
conn = psycopg2.connect(DATABASE_URL)
conn.autocommit = True
warnings = 0
for sql_file in MIGRATIONS:
path = os.path.join("/app", sql_file)
if not os.path.exists(path):
print(f" SKIP: {sql_file} (not found)")
continue
print(f"Running {sql_file}...")
ok = run_file(conn, path, sql_file)
if not ok:
warnings += 1
# Reconnect for the next file
conn = psycopg2.connect(DATABASE_URL)
conn.autocommit = True
conn.close()
if warnings:
print(f"Completed with {warnings} warning(s) (expected on re-deploy).")
else:
print("All migrations applied cleanly.")
sys.exit(0)
if __name__ == "__main__":
main()