from sqlalchemy import create_engine from sqlalchemy.orm import declarative_base, sessionmaker import os from dotenv import load_dotenv load_dotenv() def _build_database_url() -> str: """Construct the SQLAlchemy database URL from granular environment vars. Falls back to `DATABASE_URL` for backward compatibility. """ legacy_url = os.environ.get("DATABASE_URL", "") if legacy_url and legacy_url.strip() != "": return legacy_url driver = os.environ.get("DATABASE_DRIVER", "postgresql") host = os.environ.get("DATABASE_HOST") port = os.environ.get("DATABASE_PORT", "5432") user = os.environ.get("DATABASE_USER") password = os.environ.get("DATABASE_PASSWORD") database = os.environ.get("DATABASE_NAME") schema = os.environ.get("DATABASE_SCHEMA", "public") missing = [ var_name for var_name, value in ( ("DATABASE_HOST", host), ("DATABASE_USER", user), ("DATABASE_NAME", database), ) if not value ] if missing: raise RuntimeError( "Missing database configuration: set DATABASE_URL or provide " f"granular variables ({', '.join(missing)})" ) url = f"{driver}://{user}:{password}@{host}" if port: url += f":{port}" url += f"/{database}" if schema: url += f"?options=-csearch_path={schema}" return str(url) DATABASE_URL = _build_database_url() engine = create_engine(DATABASE_URL, echo=True, future=True) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base()