980a2db6d9
- 基础设施层 async:SQLAlchemy 异步引擎/会话、33 Repository async 化、models/security/seed 迁入 infrastructure、新增 cache.py(redis.asyncio) 与 oss.py(aioboto3) - 接口层:routers 迁 api/routers 并全 async,dependencies 迁 api/dependencies(get_db/get_current_user async) - 依赖:sqlalchemy[asyncio]/aiosqlite/asyncmy/redis/aioboto3;config 异步 URL + Redis/OSS 配置 - 删除废弃:旧同步 db/dependencies/repositories/storage - 验证:平台 19 路由 + 培训 48 路由全注册;/health /auth/login /auth/me /admin/tasks /notifications 等接口 async 可用
66 lines
1.8 KiB
Python
66 lines
1.8 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""基础设施层 · 异步 SQLAlchemy 引擎 / 会话 / 声明基类。
|
||
|
||
四层架构:基础设施层(含数据模型层)。全异步:
|
||
- 开发/默认:SQLite + aiosqlite
|
||
- 生产:MySQL + asyncmy(经 config.DATABASE_URL 切换)
|
||
每请求一个 async session(``get_session`` 依赖),事件循环内无阻塞。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from collections.abc import AsyncGenerator
|
||
|
||
from sqlalchemy.ext.asyncio import (
|
||
AsyncSession,
|
||
async_sessionmaker,
|
||
create_async_engine,
|
||
)
|
||
from sqlalchemy.orm import DeclarativeBase
|
||
|
||
from .. import config
|
||
|
||
|
||
class Base(DeclarativeBase):
|
||
"""SQLAlchemy 声明式基类(数据模型层继承)。"""
|
||
|
||
|
||
engine = create_async_engine(
|
||
config.DATABASE_URL,
|
||
pool_pre_ping=True,
|
||
)
|
||
|
||
AsyncSessionLocal = async_sessionmaker(
|
||
bind=engine,
|
||
class_=AsyncSession,
|
||
autoflush=False,
|
||
expire_on_commit=False,
|
||
)
|
||
|
||
|
||
async def init_db() -> None:
|
||
"""幂等地创建全部表(create_all 对已存在表无操作)。"""
|
||
from . import models # noqa: F401
|
||
|
||
async with engine.begin() as conn:
|
||
await conn.run_sync(Base.metadata.create_all)
|
||
|
||
|
||
async def get_session() -> AsyncGenerator[AsyncSession, None]:
|
||
"""FastAPI 依赖:请求级异步 SQLAlchemy 会话,请求结束自动关闭。"""
|
||
async with AsyncSessionLocal() as session:
|
||
yield session
|
||
|
||
|
||
def make_async_engine(db_url: str):
|
||
"""按给定 URL 创建独立异步引擎(测试用 tmp 数据库)。"""
|
||
return create_async_engine(db_url, pool_pre_ping=True)
|
||
|
||
|
||
def make_async_session_factory(db_url: str) -> async_sessionmaker:
|
||
return async_sessionmaker(
|
||
bind=make_async_engine(db_url),
|
||
class_=AsyncSession,
|
||
autoflush=False,
|
||
expire_on_commit=False,
|
||
)
|