from __future__ import annotations from sqlalchemy import Engine, inspect, text from app.db.models import Base def _has_column(engine: Engine, table: str, col: str) -> bool: insp = inspect(engine) cols = insp.get_columns(table) return any(c.get("name") == col for c in cols) def ensure_schema(engine: Engine) -> None: """ 轻量自升级(跨 SQLite/PostgreSQL): - create_all 不会更新既有表结构,因此用 inspector + ALTER TABLE 补列 - 必须保证任何失败都不影响主流程(上层可选择忽略异常) """ Base.metadata.create_all(bind=engine) with engine.begin() as conn: # job_logs.run_log if not _has_column(engine, "job_logs", "run_log"): conn.execute(text("ALTER TABLE job_logs ADD COLUMN run_log TEXT NOT NULL DEFAULT ''"))