refactor(db)!: finalize pooled WNDB v2 migration

This commit is contained in:
2026-08-27 17:26:22 +08:00
parent fa188af0b1
commit b74799a39d
105 changed files with 4988 additions and 5565 deletions
+52 -101
View File
@@ -1,5 +1,6 @@
import json
from datetime import datetime
from functools import wraps
from math import pi, sqrt
import pytz
@@ -9,6 +10,7 @@ from app.algorithms.simulation.runner import (
run_simulation_ex,
from_clock_to_seconds_2,
)
from app.native.wndb.core.projects import temporary_project_database
from app.services.tjnetwork import (
ChangeSet,
OPTION_DEMAND_MODEL_PDA,
@@ -16,9 +18,6 @@ from app.services.tjnetwork import (
SOURCE_TYPE_SETPOINT,
add_pattern,
add_source,
close_project,
copy_project,
delete_project,
get_demand,
get_emitter,
get_node_links,
@@ -27,10 +26,7 @@ from app.services.tjnetwork import (
get_pipe,
get_source,
get_time,
have_project,
is_junction,
is_project_open,
open_project,
set_demand,
set_emitter,
set_option,
@@ -39,11 +35,23 @@ from app.services.tjnetwork import (
)
def _isolated_analysis(purpose: str):
def decorator(func):
@wraps(func)
def wrapper(name: str, *args, **kwargs):
with temporary_project_database(name, purpose) as temporary:
kwargs["_temporary_project"] = temporary
return func(name, *args, **kwargs)
return wrapper
return decorator
############################################################
# burst analysis 01
############################################################
def convert_to_local_unit(proj: str, emitters: float) -> float:
open_project(proj)
proj_opt = get_option(proj)
str_unit = proj_opt.get("UNITS")
@@ -61,6 +69,7 @@ def convert_to_local_unit(proj: str, emitters: float) -> float:
return emitters
@_isolated_analysis("burst_analysis")
def burst_analysis(
name: str,
modify_pattern_start_time: str,
@@ -72,6 +81,7 @@ def burst_analysis(
modify_valve_opening: dict[str, float] = None,
scheme_name: str = None,
username: str | None = None,
_temporary_project: str | None = None,
) -> None:
"""
爆管模拟
@@ -101,21 +111,17 @@ def burst_analysis(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Analysis."
)
new_name = f"burst_Anal_{name}"
if have_project(new_name):
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
if _temporary_project is None:
raise RuntimeError("Burst analysis isolation was not prepared")
new_name = _temporary_project
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Copying Database."
)
copy_project(name + "_template", new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Opening Database."
)
open_project(new_name)
simulation.run_simulation(
name=new_name,
simulation_type="manually_temporary",
@@ -207,20 +213,19 @@ def burst_analysis(
)
# step 3. restore the base model status
# execute_undo(name) #有疑惑
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
############################################################
# valve closing analysis 02
############################################################
@_isolated_analysis("valve_close_analysis")
def valve_close_analysis(
name: str,
modify_pattern_start_time: str,
modify_total_duration: int = 900,
modify_valve_opening: dict[str, float] = None,
scheme_name: str = None,
_temporary_project: str | None = None,
) -> None:
"""
关阀模拟
@@ -235,21 +240,17 @@ def valve_close_analysis(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Analysis."
)
new_name = f"valve_close_Anal_{name}"
if have_project(new_name):
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
if _temporary_project is None:
raise RuntimeError("Valve-close analysis isolation was not prepared")
new_name = _temporary_project
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Copying Database."
)
copy_project(name + "_template", new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Opening Database."
)
open_project(new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Database Loading OK."
@@ -287,9 +288,6 @@ def valve_close_analysis(
# step 3. restore the base model
# for valve in valves:
# execute_undo(name)
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
# return result
@@ -297,6 +295,7 @@ def valve_close_analysis(
# flushing analysis 03
# Pipe_Flushing_Analysis(prj_name,date_time, Valve_id_list, Drainage_Node_Id, Flushing_flow[opt], Flushing_duration[opt])->out_file:string
############################################################
@_isolated_analysis("flushing_analysis")
def flushing_analysis(
name: str,
modify_pattern_start_time: str,
@@ -307,6 +306,7 @@ def flushing_analysis(
scheme_name: str = None,
username: str | None = None,
valve_control: dict[str, dict] = None,
_temporary_project: str | None = None,
) -> None:
"""
管道冲洗模拟
@@ -334,23 +334,17 @@ def flushing_analysis(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Analysis."
)
new_name = f"flushing_Anal_{name}"
if have_project(new_name):
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
# if is_project_open(name):
# close_project(name)
if _temporary_project is None:
raise RuntimeError("Flushing analysis isolation was not prepared")
new_name = _temporary_project
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Copying Database."
)
copy_project(name + "_template", new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Opening Database."
)
open_project(new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Database Loading OK."
@@ -449,9 +443,6 @@ def flushing_analysis(
scheme_detail=scheme_detail,
)
# step 4. restore the base model
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
# return result
@@ -459,6 +450,7 @@ def flushing_analysis(
# Contaminant simulation 04
#
############################################################
@_isolated_analysis("contaminant_simulation")
def contaminant_simulation(
name: str,
modify_pattern_start_time: str, # 模拟开始时间,格式为'2024-11-25T09:00:00+08:00'
@@ -468,6 +460,7 @@ def contaminant_simulation(
scheme_name: str = None,
source_pattern: str = None, # 污染源时间变化模式名称
username: str | None = None,
_temporary_project: str | None = None,
) -> None:
"""
污染模拟
@@ -494,23 +487,17 @@ def contaminant_simulation(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Analysis."
)
new_name = f"contaminant_Sim_{name}"
if have_project(new_name):
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
# if is_project_open(name):
# close_project(name)
if _temporary_project is None:
raise RuntimeError("Contaminant simulation isolation was not prepared")
new_name = _temporary_project
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Copying Database."
)
copy_project(name + "_template", new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Opening Database."
)
open_project(new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Database Loading OK."
@@ -599,9 +586,6 @@ def contaminant_simulation(
# for i in range(1,operation_step):
# execute_undo(name)
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
############################################################
@@ -623,45 +607,19 @@ def age_analysis(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Analysis."
)
new_name = f"age_Anal_{name}"
if have_project(new_name):
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
# if is_project_open(name):
# close_project(name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Copying Database."
)
copy_project(name + "_template", new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Opening Database."
)
open_project(new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Database Loading OK."
)
# step 1. run simulation
with temporary_project_database(name, "age_analysis") as new_name:
result = run_simulation_ex(
new_name,
"realtime",
modify_pattern_start_time,
duration=modify_total_duration,
downloading_prohibition=True,
)
simulation_result = json.loads(result)
output_data = simulation_result.get("output")
if not isinstance(output_data, dict):
raise RuntimeError("run_simulation_ex did not return JSON output content")
result = run_simulation_ex(
new_name,
"realtime",
modify_pattern_start_time,
duration=modify_total_duration,
downloading_prohibition=True,
)
simulation_result = json.loads(result)
output_data = simulation_result.get("output")
if not isinstance(output_data, dict):
raise RuntimeError("run_simulation_ex did not return JSON output content")
# step 2. restore the base model status
# execute_undo(name) #有疑惑
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
nodes_age = []
node_result = output_data.get("node_results") or []
for node in node_result:
@@ -680,6 +638,7 @@ def age_analysis(
############################################################
@_isolated_analysis("pressure_regulation")
def pressure_regulation(
name: str,
modify_pattern_start_time: str,
@@ -688,6 +647,7 @@ def pressure_regulation(
modify_fixed_pump_pattern: dict[str, list] = None,
modify_variable_pump_pattern: dict[str, list] = None,
scheme_name: str = None,
_temporary_project: str | None = None,
) -> None:
"""
区域调压模拟,用来模拟未来15分钟内,开关水泵对区域压力的影响
@@ -704,23 +664,17 @@ def pressure_regulation(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Analysis."
)
new_name = f"pressure_regulation_{name}"
if have_project(new_name):
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
# if is_project_open(name):
# close_project(name)
if _temporary_project is None:
raise RuntimeError("Pressure-regulation isolation was not prepared")
new_name = _temporary_project
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Copying Database."
)
copy_project(name + "_template", new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Start Opening Database."
)
open_project(new_name)
print(
datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
+ " -- Database Loading OK."
@@ -751,7 +705,4 @@ def pressure_regulation(
scheme_name=scheme_name,
result_db_name=name,
)
if is_project_open(new_name):
close_project(new_name)
delete_project(new_name)
# return result