保存(或更新)一个命名场景。 Parameters ---------- name: 场景名称(<=128 字符,全库唯一)。 engine: ``SimulationEngine`` 实例——用于提取资源配置。 stats: 运行统计快照(通常为 ``engine.get_stats()``); 未传入时仅保存资源配置,run_stats 置空。 Returns -------
(
self,
name: str,
engine: Any,
stats: Optional[Dict[str, Any]] = None,
)
| 115 | # ── 公共接口 ────────────────────────────────────────────────────────────── |
| 116 | |
| 117 | def save_scenario( |
| 118 | self, |
| 119 | name: str, |
| 120 | engine: Any, |
| 121 | stats: Optional[Dict[str, Any]] = None, |
| 122 | ) -> Dict[str, Any]: |
| 123 | """保存(或更新)一个命名场景。 |
| 124 | |
| 125 | Parameters |
| 126 | ---------- |
| 127 | name: |
| 128 | 场景名称(<=128 字符,全库唯一)。 |
| 129 | engine: |
| 130 | ``SimulationEngine`` 实例——用于提取资源配置。 |
| 131 | stats: |
| 132 | 运行统计快照(通常为 ``engine.get_stats()``); |
| 133 | 未传入时仅保存资源配置,run_stats 置空。 |
| 134 | |
| 135 | Returns |
| 136 | ------- |
| 137 | dict |
| 138 | 保存后的完整场景记录。 |
| 139 | """ |
| 140 | name = str(name)[:128].strip() |
| 141 | if not name: |
| 142 | raise ValueError("场景名称不可为空") |
| 143 | |
| 144 | scene = ScenarioManager.save(engine, name=name) |
| 145 | run_stats: Dict[str, Any] = {} |
| 146 | if stats is not None: |
| 147 | # 仅保留决策指标与请求统计,避免写入大型原始数据 |
| 148 | run_stats = { |
| 149 | "total_requests": stats.get("total_requests", 0), |
| 150 | "accepted_requests": stats.get("accepted_requests", 0), |
| 151 | "rejected_requests": stats.get("rejected_requests", 0), |
| 152 | "completed_requests": stats.get("completed_requests", 0), |
| 153 | "decision_metrics": stats.get("decision_metrics", {}), |
| 154 | "rejection_distribution": stats.get("rejection_distribution", {}), |
| 155 | } |
| 156 | |
| 157 | saved_at = datetime.now(tz=timezone.utc).isoformat() |
| 158 | data_types_json = json.dumps(scene.get("data_types", []), ensure_ascii=False) |
| 159 | run_stats_json = json.dumps(run_stats, ensure_ascii=False) |
| 160 | |
| 161 | with self._lock, self._conn: |
| 162 | self._conn.execute( |
| 163 | """INSERT INTO scenarios |
| 164 | (name, version, saved_at, is_baseline, gs_count, leo_count, geo_count, data_types, run_stats) |
| 165 | VALUES (?, ?, ?, 0, ?, ?, ?, ?, ?) |
| 166 | ON CONFLICT(name) DO UPDATE SET |
| 167 | version=excluded.version, |
| 168 | saved_at=excluded.saved_at, |
| 169 | gs_count=excluded.gs_count, |
| 170 | leo_count=excluded.leo_count, |
| 171 | geo_count=excluded.geo_count, |
| 172 | data_types=excluded.data_types, |
| 173 | run_stats=excluded.run_stats""", |
| 174 | ( |