from sqlalchemy import create_engine, inspect, text from sqlalchemy.orm import sessionmaker, DeclarativeBase import os DB_PATH = os.environ.get("DB_PATH", "/app/data/agents.db") engine = create_engine(f"sqlite:///{DB_PATH}", connect_args={"check_same_thread": False}) SessionLocal = sessionmaker(bind=engine) class Base(DeclarativeBase): pass def get_db(): db = SessionLocal() try: yield db finally: db.close() def _ensure_column(conn, table: str, column: str, ddl: str): """Add a column to an existing table if it doesn't exist (SQLite idempotent migration).""" insp = inspect(conn) cols = {c["name"] for c in insp.get_columns(table)} if column not in cols: conn.execute(text(f"ALTER TABLE {table} ADD COLUMN {column} {ddl}")) print(f" migration: added {table}.{column}") def init_db(): Base.metadata.create_all(bind=engine) with engine.begin() as conn: # Additive columns on existing tables (safe to re-run) _ensure_column(conn, "runs", "result", "JSON") _ensure_column(conn, "runs", "triggered_by", "VARCHAR DEFAULT ''") _ensure_column(conn, "agent_catalog", "result_schema", "JSON")