c9a99f4fb3
代码修复: - web/agent/agent.py: datetime.utcnow() → datetime.now(timezone.utc) - requirements.txt: 移除 paramiko==3.5.0 (已无活跃引用) - 删除 server/infrastructure/ssh/pool.py (DEPRECATED, 无引用) 连接池三层对齐 (config.py/.env.example/session.py): - DB_POOL_SIZE 100→160, DB_MAX_OVERFLOW 100→120 - 基于 MySQL max_connections=400, install.php 公式 文档修复 (21项): - P0: 硬编码域名/IP替换为配置变量占位符 - P1: 10个过时设计文档加归档标注 (引用旧文件结构) - P2: step-3-webssh报告 paramiko引用修正 - 6份审查报告连接池参数勘误 100/100→160/120 - ECC安全报告 EC5 datetime.utcnow 标记已修复 - docs/README.md 文档索引重写 - docs/memory/mem_nexus_overview.md 移除硬编码凭证 - docs/project/tech-stack-inventory.md paramiko标记已移除 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
1.8 KiB
Python
72 lines
1.8 KiB
Python
"""Nexus — Database Session Management (Async SQLAlchemy)
|
|
Engine is created lazily to allow testing without MySQL.
|
|
"""
|
|
|
|
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
|
|
from server.domain.models import Base
|
|
from server.config import settings
|
|
|
|
_engine = None
|
|
_session_factory = None
|
|
|
|
|
|
def _ensure_engine():
|
|
"""Lazily create engine on first access (not at import time)"""
|
|
global _engine, _session_factory
|
|
if _engine is None:
|
|
_engine = create_async_engine(
|
|
settings.DATABASE_URL.replace("mysql+pymysql", "mysql+aiomysql"),
|
|
pool_size=max(5, int(settings.DB_POOL_SIZE or 160)),
|
|
max_overflow=max(5, int(settings.DB_MAX_OVERFLOW or 120)),
|
|
pool_recycle=300,
|
|
pool_pre_ping=True,
|
|
)
|
|
_session_factory = async_sessionmaker(
|
|
autocommit=False,
|
|
autoflush=False,
|
|
bind=_engine,
|
|
class_=AsyncSession,
|
|
)
|
|
|
|
|
|
def get_engine():
|
|
_ensure_engine()
|
|
return _engine
|
|
|
|
|
|
@property
|
|
def AsyncSessionLocal():
|
|
_ensure_engine()
|
|
return _session_factory
|
|
|
|
|
|
class _SessionLocalProxy:
|
|
"""Proxy that defers session factory creation until first call"""
|
|
def __call__(self):
|
|
_ensure_engine()
|
|
return _session_factory()
|
|
|
|
def __getattr__(self, name):
|
|
_ensure_engine()
|
|
return getattr(_session_factory, name)
|
|
|
|
|
|
AsyncSessionLocal = _SessionLocalProxy()
|
|
|
|
|
|
async def get_async_session():
|
|
"""Dependency injection: yield async DB session"""
|
|
_ensure_engine()
|
|
session = _session_factory()
|
|
try:
|
|
yield session
|
|
finally:
|
|
await session.close()
|
|
|
|
|
|
async def init_db():
|
|
"""Initialize database tables"""
|
|
_ensure_engine()
|
|
async with _engine.begin() as conn:
|
|
await conn.run_sync(Base.metadata.create_all)
|