refactor(db)!: clean up business SQL access

- make realtime replacement and analysis result writes transactional\n- consolidate SCADA repositories and remove process-global project state\n- validate SCADA batches and use indexed GIS-backed business queries\n\nBREAKING CHANGE: remove the public analysis result writer and the pipeline-health network_name query parameter.
This commit is contained in:
2026-08-28 11:37:36 +08:00
parent b74799a39d
commit 9b095c7439
34 changed files with 859 additions and 921 deletions
+98 -2
View File
@@ -1,9 +1,105 @@
from uuid import UUID
from datetime import datetime
from typing import Any
from uuid import UUID, uuid4
from psycopg import AsyncConnection
from psycopg import AsyncConnection, Connection
from psycopg.types.json import Jsonb
class AnalysisRepository:
@staticmethod
def create_run_sync(
conn: Connection,
*,
name: str,
run_type: str,
created_by: str,
started_at: datetime,
status: str,
parameters: dict[str, Any],
run_id: UUID | None = None,
) -> dict[str, Any]:
execution_id = run_id or uuid4()
with conn.cursor() as cur:
cur.execute(
"""
INSERT INTO analysis.runs
(run_id, name, run_type, created_by, created_at,
started_at, status, parameters)
VALUES (%s, %s, %s, %s, now(), %s, %s, %s)
RETURNING run_id, name, run_type, created_by, created_at,
started_at, status, parameters
""",
(
execution_id,
name,
run_type,
created_by,
started_at,
status,
Jsonb(parameters),
),
)
created = cur.fetchone()
if created is None:
raise RuntimeError("analysis run insert returned no row")
return created
@staticmethod
def update_run_sync(
conn: Connection,
run_id: UUID,
*,
status: str,
created_by: str,
parameters: dict[str, Any],
) -> None:
with conn.cursor() as cur:
cur.execute(
"""
UPDATE analysis.runs
SET created_by = %s, status = %s, parameters = %s
WHERE run_id = %s
""",
(created_by, status, Jsonb(parameters), run_id),
)
if cur.rowcount != 1:
raise LookupError(f"analysis run {run_id} does not exist")
@staticmethod
def insert_result_sync(
conn: Connection,
run_id: UUID,
*,
result_type: str,
payload: dict[str, Any],
node_id: str | None = None,
link_id: str | None = None,
) -> None:
with conn.cursor() as cur:
cur.execute(
"""
INSERT INTO analysis.results
(run_id, result_type, node_id, link_id, payload)
VALUES (%s, %s, %s, %s, %s)
""",
(run_id, result_type, node_id, link_id, Jsonb(payload)),
)
@staticmethod
def get_run_sync(conn: Connection, run_id: UUID) -> dict[str, Any] | None:
with conn.cursor() as cur:
cur.execute(
"""
SELECT run_id, name, run_type, created_by, created_at,
started_at, status, parameters
FROM analysis.runs
WHERE run_id = %s
""",
(run_id,),
)
return cur.fetchone()
@staticmethod
async def list_runs(conn: AsyncConnection) -> list[dict]:
async with conn.cursor() as cur: