Files
2026-09-21 19:03:31 +08:00

67 lines
1.8 KiB
Python

"""数据库引擎 / 会话 / 依赖注入 / 自动建库。"""
from __future__ import annotations
import logging
from collections.abc import Generator
from sqlalchemy import create_engine, text
from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session, sessionmaker
from app.core.config import settings
logger = logging.getLogger(__name__)
def _build_engine() -> Engine:
if settings.DB_DRIVER.startswith("sqlite"):
return create_engine(
settings.database_url,
echo=settings.DB_ECHO,
connect_args={"check_same_thread": False},
)
return create_engine(
settings.database_url,
echo=settings.DB_ECHO,
pool_size=settings.DB_POOL_SIZE,
pool_recycle=settings.DB_POOL_RECYCLE,
pool_pre_ping=True,
future=True,
)
engine: Engine = _build_engine()
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False, class_=Session)
def ensure_database_exists() -> None:
"""MySQL 下若目标库不存在则自动创建,省去手工建库。"""
if settings.DB_DRIVER.startswith("sqlite"):
return
root_engine = create_engine(settings.server_url_without_db, future=True)
try:
with root_engine.connect() as conn:
conn.execute(
text(
f"CREATE DATABASE IF NOT EXISTS `{settings.DB_NAME}` "
f"DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"
)
)
conn.commit()
finally:
root_engine.dispose()
def get_db() -> Generator[Session, None, None]:
"""FastAPI 依赖:每个请求一个会话,结束即关闭。"""
db = SessionLocal()
try:
yield db
finally:
db.close()
def dialect_name() -> str:
return engine.dialect.name