Files
app-autotest/site/db/init_db.py
T

72 lines
2.2 KiB
Python

"""
Инициализация схемы БД — идемпотентно (CREATE IF NOT EXISTS).
Вызывается при старте приложения (в app.py, до register_blueprint).
Безопасно для нескольких gunicorn-воркеров — PostgreSQL корректно
обрабатывает конкурентный DDL.
Таблица runs — история запусков операций:
- id, created_at
- client_id, stand (изоляция по пользователю и стенду)
- svc_id, svc_name, op_name, svc_op_id
- instance_uid, display_name
- status (OK/FAIL/TIMEOUT), duration_sec, error_log
- params (JSONB), stages (JSONB)
"""
import os
from db.pool import get_conn, put_conn
SCHEMA_SQL = """
CREATE TABLE IF NOT EXISTS runs (
id SERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
client_id VARCHAR(64) NOT NULL,
stand VARCHAR(16) NOT NULL,
svc_id INTEGER NOT NULL,
svc_name VARCHAR(128),
op_name VARCHAR(32) NOT NULL,
svc_op_id INTEGER,
instance_uid VARCHAR(64),
display_name VARCHAR(255),
status VARCHAR(16) NOT NULL,
duration_sec DOUBLE PRECISION,
error_log TEXT,
params JSONB,
stages JSONB
);
CREATE INDEX IF NOT EXISTS idx_runs_client_stand
ON runs (client_id, stand, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_runs_instance
ON runs (instance_uid);
CREATE INDEX IF NOT EXISTS idx_runs_created
ON runs (created_at);
"""
def init_db():
"""Применить схему — идемпотентно, безопасно для конкурентного вызова."""
if not os.getenv("DB_USER"):
print("[DB] DB_USER not set — skipping init", flush=True)
return
conn = get_conn()
if not conn:
print("[DB] Failed to get connection — skipping init", flush=True)
return
try:
cur = conn.cursor()
cur.execute(SCHEMA_SQL)
conn.commit()
cur.close()
print("[DB] Schema initialized", flush=True)
except Exception as e:
print(f"[DB] Init error: {e}", flush=True)
conn.rollback()
finally:
put_conn(conn)