from sqlalchemy import create_engine, inspect, text from sqlalchemy.orm import DeclarativeBase, sessionmaker from app.config import settings engine = create_engine( settings.database_url, connect_args={"check_same_thread": False} if settings.database_url.startswith("sqlite") else {}, future=True, ) SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, future=True) class Base(DeclarativeBase): pass def get_db(): db = SessionLocal() try: yield db finally: db.close() def init_db(): from app import models # noqa: F401 — registers models on Base Base.metadata.create_all(bind=engine) _migrate_employees_portal_user_id() _migrate_competitor_listings_auto_fields() def _migrate_employees_portal_user_id() -> None: inspector = inspect(engine) if "employees" not in inspector.get_table_names(): return columns = {col["name"] for col in inspector.get_columns("employees")} with engine.begin() as conn: if "portal_user_id" not in columns: conn.execute(text("ALTER TABLE employees ADD COLUMN portal_user_id VARCHAR(100)")) conn.execute( text("CREATE UNIQUE INDEX IF NOT EXISTS ix_employees_portal_user_id ON employees (portal_user_id)") ) def _migrate_competitor_listings_auto_fields() -> None: inspector = inspect(engine) if "competitor_listings" not in inspector.get_table_names(): return columns = {col["name"] for col in inspector.get_columns("competitor_listings")} with engine.begin() as conn: if "permit_number" not in columns: conn.execute(text("ALTER TABLE competitor_listings ADD COLUMN permit_number VARCHAR(100)")) if "auto_discovered" not in columns: conn.execute(text("ALTER TABLE competitor_listings ADD COLUMN auto_discovered BOOLEAN NOT NULL DEFAULT 0"))