fix(rls): 收斂 API DB access context
This commit is contained in:
@@ -842,14 +842,13 @@ class AIRouter:
|
||||
空 dict 代表無資料或查詢失敗(caller 應降級為忽略)。
|
||||
"""
|
||||
try:
|
||||
from src.db.base import get_session_factory
|
||||
from src.db.base import get_db_context
|
||||
from src.repositories.aider_event_repository import AiderEventRepository
|
||||
except ImportError:
|
||||
return {}
|
||||
|
||||
try:
|
||||
sf = get_session_factory()
|
||||
async with sf() as sess:
|
||||
async with get_db_context() as sess:
|
||||
repo_obj = AiderEventRepository(sess)
|
||||
stats = await repo_obj.model_stats_since(days=days)
|
||||
except Exception:
|
||||
|
||||
@@ -28,7 +28,7 @@ from datetime import timedelta
|
||||
import structlog
|
||||
from sqlalchemy import func, select, text
|
||||
|
||||
from src.db.base import get_session_factory
|
||||
from src.db.base import get_db_context
|
||||
from src.db.models import AiGovernanceEvent, AutoRepairExecution, ApprovalRecord
|
||||
from src.utils.timezone import now_taipei
|
||||
|
||||
@@ -127,7 +127,7 @@ class AiSloCalculator:
|
||||
try:
|
||||
since = now_taipei() - timedelta(days=SLO_WINDOW_DAYS)
|
||||
|
||||
async with get_session_factory()() as session:
|
||||
async with get_db_context() as session:
|
||||
slo1 = await self._calc_auto_success_rate(session, since)
|
||||
slo2 = await self._calc_human_override_rate(session, since)
|
||||
slo3 = await self._calc_false_neg_rate(session, since)
|
||||
@@ -210,7 +210,7 @@ class AiSloCalculator:
|
||||
只在 any_violated=True 時呼叫。不管舊違反是否解決。
|
||||
"""
|
||||
try:
|
||||
async with get_session_factory()() as session:
|
||||
async with get_db_context() as session:
|
||||
event = AiGovernanceEvent(
|
||||
event_type="slo_violation",
|
||||
details=report.to_dict(),
|
||||
|
||||
@@ -1933,14 +1933,14 @@ class DecisionManager:
|
||||
try:
|
||||
from src.core.feature_flags import aiops_flags as _p6_flags
|
||||
if _p6_flags.is_sub_flag_enabled("AIOPS_P6_SELF_DEMOTION"):
|
||||
from src.db.base import get_session_factory as _p6_sf
|
||||
from src.db.base import get_db_context as _p6_db_context
|
||||
from src.db.models import AiGovernanceEvent as _GovernanceEvent
|
||||
from sqlalchemy import select as _p6_select, func as _p6_func
|
||||
from datetime import timedelta as _p6_td
|
||||
|
||||
_now = __import__("src.utils.timezone", fromlist=["now_taipei"]).now_taipei()
|
||||
|
||||
async with _p6_sf()() as _p6_sess:
|
||||
async with _p6_db_context() as _p6_sess:
|
||||
# 過去 7 天有幾筆未解決的 slo_violation?
|
||||
_viol_7d_q = await _p6_sess.execute(
|
||||
_p6_select(_p6_func.count()).where(
|
||||
@@ -1980,8 +1980,8 @@ class DecisionManager:
|
||||
)
|
||||
# 記錄保守模式事件
|
||||
try:
|
||||
from src.db.base import get_session_factory as _p6_sf2
|
||||
async with _p6_sf2()() as _s2:
|
||||
from src.db.base import get_db_context as _p6_db_context2
|
||||
async with _p6_db_context2() as _s2:
|
||||
_s2.add(_GovernanceEvent(
|
||||
event_type="conservative_mode",
|
||||
details={
|
||||
@@ -2021,8 +2021,8 @@ class DecisionManager:
|
||||
_push_decision_to_telegram(incident, token.proposal_data)
|
||||
)
|
||||
try:
|
||||
from src.db.base import get_session_factory as _p6_sf3
|
||||
async with _p6_sf3()() as _s3:
|
||||
from src.db.base import get_db_context as _p6_db_context3
|
||||
async with _p6_db_context3() as _s3:
|
||||
_s3.add(_GovernanceEvent(
|
||||
event_type="self_demotion",
|
||||
details={
|
||||
|
||||
@@ -424,11 +424,10 @@ class DynamicBaselineService:
|
||||
async def _pg_upsert_baseline(self, state: BaselineState, promql: str, lookback_hours: int) -> None:
|
||||
"""寫入 DynamicBaselineRecord 到 PostgreSQL(INSERT,不更新舊記錄)"""
|
||||
try:
|
||||
from src.db.base import get_session_factory
|
||||
from src.db.base import get_db_context
|
||||
from src.db.models import DynamicBaselineRecord
|
||||
|
||||
factory = get_session_factory()
|
||||
async with factory() as session:
|
||||
async with get_db_context() as session:
|
||||
record = DynamicBaselineRecord(
|
||||
metric_name=state.metric_name,
|
||||
mean=state.mean,
|
||||
@@ -449,11 +448,10 @@ class DynamicBaselineService:
|
||||
try:
|
||||
from sqlalchemy import select
|
||||
|
||||
from src.db.base import get_session_factory
|
||||
from src.db.base import get_db_context
|
||||
from src.db.models import DynamicBaselineRecord
|
||||
|
||||
factory = get_session_factory()
|
||||
async with factory() as session:
|
||||
async with get_db_context() as session:
|
||||
stmt = (
|
||||
select(DynamicBaselineRecord)
|
||||
.where(DynamicBaselineRecord.metric_name == metric_name)
|
||||
|
||||
@@ -52,7 +52,7 @@ from pathlib import Path
|
||||
import structlog
|
||||
from sqlalchemy import and_, select, text as sql_text
|
||||
|
||||
from src.db.base import get_session_factory
|
||||
from src.db.base import get_db_context
|
||||
from src.db.models import AgentSession, AutoRepairExecution, IncidentEvidence
|
||||
from src.utils.timezone import now_taipei
|
||||
|
||||
@@ -107,9 +107,7 @@ class FineTuneExporter:
|
||||
|
||||
async def _run_export(self) -> tuple[str | None, int]:
|
||||
cutoff = now_taipei() - timedelta(days=EXPORT_LOOKBACK_DAYS)
|
||||
session_factory = get_session_factory()
|
||||
|
||||
async with session_factory() as db:
|
||||
async with get_db_context() as db:
|
||||
# 1. 取得成功驗證的 EvidenceSnapshot(有 evidence_summary + verification_result='success')
|
||||
stmt = select(IncidentEvidence).where(
|
||||
and_(
|
||||
@@ -153,7 +151,7 @@ class FineTuneExporter:
|
||||
with open(output_path, 'rb') as _f:
|
||||
_checksum = hashlib.sha256(_f.read()).hexdigest()
|
||||
_ids = [str(ev.id) for ev in evidences]
|
||||
async with session_factory() as _db:
|
||||
async with get_db_context() as _db:
|
||||
await _db.execute(
|
||||
sql_text("""
|
||||
INSERT INTO finetune_exports (
|
||||
|
||||
@@ -296,12 +296,11 @@ class LogAnomalyDetector:
|
||||
"""
|
||||
try:
|
||||
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
||||
from src.db.base import get_session_factory
|
||||
from src.db.base import get_db_context
|
||||
from src.db.models import LogClusterRecord
|
||||
from src.utils.timezone import now_taipei
|
||||
|
||||
factory = get_session_factory()
|
||||
async with factory() as session:
|
||||
async with get_db_context() as session:
|
||||
stmt = pg_insert(LogClusterRecord).values(
|
||||
cluster_id=cluster.cluster_id,
|
||||
template=cluster.template,
|
||||
|
||||
@@ -39,7 +39,7 @@ from dataclasses import dataclass
|
||||
import structlog
|
||||
from sqlalchemy import func, select
|
||||
|
||||
from src.db.base import get_session_factory
|
||||
from src.db.base import get_db_context
|
||||
from src.db.models import AiGovernanceEvent, PlaybookRecord
|
||||
from src.utils.timezone import now_taipei
|
||||
|
||||
@@ -115,7 +115,7 @@ class TrustDriftDetector:
|
||||
TrustDistribution(樣本不足時 drift_detected=False)
|
||||
"""
|
||||
try:
|
||||
async with get_session_factory()() as session:
|
||||
async with get_db_context() as session:
|
||||
# 只計算 approved 狀態的 Playbook
|
||||
total_q = await session.execute(
|
||||
select(func.count()).where(
|
||||
@@ -215,7 +215,7 @@ class TrustDriftDetector:
|
||||
async def save_drift_event(self, dist: TrustDistribution) -> None:
|
||||
"""將信任度漂移事件寫入 ai_governance_events。"""
|
||||
try:
|
||||
async with get_session_factory()() as session:
|
||||
async with get_db_context() as session:
|
||||
event = AiGovernanceEvent(
|
||||
event_type="trust_drift",
|
||||
details={
|
||||
|
||||
Reference in New Issue
Block a user