feat: TenantRuntime/Registry——每租户懒建 engine(WAL/pool2)+文件加载器+站点解析

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-12 18:24:47 +08:00
parent f5f54383fc
commit 607baff83c
6 changed files with 435 additions and 22 deletions
+2 -21
View File
@@ -2,11 +2,10 @@ from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from app.engine.config import settings, ensure_dirs, STATIC_DIR
from app.engine.models import Base
from app.engine.models import ensure_schema
# 后台推送任务的独立连接写结果可能撞上 SMTP 窗口内持有的写锁,默认 5s
@@ -16,28 +15,10 @@ engine = create_async_engine(settings.DATABASE_URL, echo=settings.APP_DEBUG,
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async def _migrate(conn):
result = await conn.execute(text("PRAGMA table_info(conversations)"))
columns = {row[1] for row in result}
if "page_token" not in columns:
await conn.execute(text(
"ALTER TABLE conversations ADD COLUMN page_token VARCHAR(64)"
))
result = await conn.execute(text("PRAGMA table_info(evaluations)"))
columns = {row[1] for row in result}
if "correction_count" not in columns:
await conn.execute(text(
"ALTER TABLE evaluations ADD COLUMN correction_count INTEGER DEFAULT 0"
))
@asynccontextmanager
async def lifespan(app: FastAPI):
ensure_dirs()
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
await _migrate(conn)
await ensure_schema(engine)
# 询盘推送(设计 8.2): 清扫崩溃遗留的 stale pending → failed
# 函数内导入: lead_push_service 顶部 from app.main import async_session,
# 顶层互相导入会循环