"""数据库引擎、Session 与 Declarative Base。 引擎采用懒初始化:首次访问 `get_engine()` 时才创建连接池, 避免 import 时的副作用,并支持 `dispose()` 后重新加载配置。 """ from __future__ import annotations from collections.abc import Generator from sqlalchemy import create_engine from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker from .config import get_settings _engine: create_engine | None = None _session_local: sessionmaker | None = None def get_engine() -> create_engine: """返回全局 Engine 实例;首次调用时懒创建。""" global _engine, _session_local if _engine is None: s = get_settings() _engine = create_engine( s.db_url(), pool_pre_ping=True, pool_size=s.database.pool_size, pool_recycle=s.database.pool_recycle, future=True, ) _session_local = sessionmaker( bind=_engine, autoflush=False, autocommit=False, future=True, ) return _engine def dispose_engine() -> None: """关闭连接池并清除缓存,下次访问时重新创建(配合 reload_settings 使用)。""" global _engine, _session_local if _engine is not None: _engine.dispose() _engine = None _session_local = None def get_session_local() -> sessionmaker: """返回全局 SessionLocal;确保 Engine 已初始化。""" get_engine() return _session_local # type: ignore[return-value] class Base(DeclarativeBase): pass def get_db() -> Generator[Session, None, None]: """FastAPI 依赖:为每个请求产出一个 Session。""" db = get_session_local()() try: yield db finally: db.close() def init_db_schema() -> None: """按需建表(幂等)。先导入 models 以注册映射。""" from . import models # noqa: F401 get_engine() Base.metadata.create_all(bind=_engine)