Spaces:
Running
Running
| from sqlalchemy import create_engine, event | |
| from sqlalchemy.orm import DeclarativeBase, sessionmaker | |
| from config import settings | |
| engine = create_engine( | |
| settings.DATABASE_URL, | |
| connect_args={"check_same_thread": False} if settings.DATABASE_URL.startswith("sqlite") else {}, | |
| pool_pre_ping=True, | |
| pool_recycle=300, | |
| ) | |
| if settings.DATABASE_URL.startswith("sqlite"): | |
| def _sqlite_on_connect(dbapi_conn, _): | |
| # Enforce FK constraints (needed for ON DELETE SET NULL) + WAL for better | |
| # concurrent reads while a writer is active. | |
| cur = dbapi_conn.cursor() | |
| cur.execute("PRAGMA foreign_keys=ON") | |
| cur.execute("PRAGMA journal_mode=WAL") | |
| cur.close() | |
| SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) | |
| class Base(DeclarativeBase): | |
| pass | |
| def get_db(): | |
| db = SessionLocal() | |
| try: | |
| yield db | |
| finally: | |
| db.close() | |
| def init_db(): | |
| from db import models # noqa: F401 | |
| from sqlalchemy import inspect, text | |
| Base.metadata.create_all(bind=engine) | |
| # Phase 19.4 — lightweight in-place migration for new columns. | |
| # Alembic is overkill here; just ALTER TABLE when a new column is missing. | |
| insp = inspect(engine) | |
| if "analyses" in insp.get_table_names(): | |
| existing = {c["name"] for c in insp.get_columns("analyses")} | |
| with engine.begin() as conn: | |
| if "media_hash" not in existing: | |
| conn.execute(text("ALTER TABLE analyses ADD COLUMN media_hash VARCHAR(64)")) | |
| if "media_path" not in existing: | |
| conn.execute(text("ALTER TABLE analyses ADD COLUMN media_path VARCHAR(512)")) | |
| if "thumbnail_url" not in existing: | |
| conn.execute(text("ALTER TABLE analyses ADD COLUMN thumbnail_url VARCHAR(512)")) | |
| # Indices (CREATE INDEX IF NOT EXISTS is SQLite+Postgres safe) | |
| for ddl in ( | |
| "CREATE INDEX IF NOT EXISTS ix_analyses_media_hash ON analyses (media_hash)", | |
| "CREATE INDEX IF NOT EXISTS ix_record_user_created ON analyses (user_id, created_at)", | |
| "CREATE INDEX IF NOT EXISTS ix_report_analysis ON reports (analysis_id)", | |
| ): | |
| try: | |
| conn.execute(text(ddl)) | |
| except Exception: # noqa: BLE001 | |
| pass | |