Files
zTools2/app/database.py
zikai e5a725fc91 fix: database.py 懒初始化引擎 + list_files 返回真实 total
- database.py: engine/SessionLocal 改为延迟创建,避免 import 时副作用,
  并提供 dispose_engine() 支持配置热重载
- dao/uploaded_file_dao.py: 新增 count() 方法
- upload_service.py: list_files() 改用 dao.count() 返回数据库总条数,
  修复之前返回当前页条目数导致分页 total 语义错误的问题
2026-06-24 07:42:30 +00:00

71 lines
1.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""数据库引擎、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)