mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Batch plan saves reduce RDS CPU during bulk modelling runs 🟪
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
46ca714ef9
commit
4764bc7c15
2 changed files with 15 additions and 41 deletions
|
|
@ -93,6 +93,7 @@ from repositories.comparable_properties.epc_comparable_properties_repository imp
|
||||||
SkippedCohortCert,
|
SkippedCohortCert,
|
||||||
)
|
)
|
||||||
from repositories.epc.epc_postgres_repository import EpcPostgresRepository, EpcSaveRequest
|
from repositories.epc.epc_postgres_repository import EpcPostgresRepository, EpcSaveRequest
|
||||||
|
from repositories.plan.plan_repository import PlanSaveRequest
|
||||||
from repositories.geospatial.geospatial_s3_repository import (
|
from repositories.geospatial.geospatial_s3_repository import (
|
||||||
GeospatialS3Repository,
|
GeospatialS3Repository,
|
||||||
ParquetReader,
|
ParquetReader,
|
||||||
|
|
@ -201,6 +202,17 @@ def _flush_writes(engine: Engine, writes: list[_PropertyWrite]) -> None:
|
||||||
uow.epc.save_batch(lodged_requests)
|
uow.epc.save_batch(lodged_requests)
|
||||||
if predicted_requests:
|
if predicted_requests:
|
||||||
uow.epc.save_batch(predicted_requests)
|
uow.epc.save_batch(predicted_requests)
|
||||||
|
plan_requests = [
|
||||||
|
PlanSaveRequest(
|
||||||
|
w.plan,
|
||||||
|
property_id=w.property_id,
|
||||||
|
scenario_id=w.scenario_id,
|
||||||
|
portfolio_id=w.portfolio_id,
|
||||||
|
is_default=w.is_default,
|
||||||
|
)
|
||||||
|
for w in writes
|
||||||
|
]
|
||||||
|
uow.plan.save_batch(plan_requests)
|
||||||
for w in writes:
|
for w in writes:
|
||||||
if w.spatial is not None:
|
if w.spatial is not None:
|
||||||
uow.spatial.save(w.uprn, w.spatial)
|
uow.spatial.save(w.uprn, w.spatial)
|
||||||
|
|
@ -211,13 +223,6 @@ def _flush_writes(engine: Engine, writes: list[_PropertyWrite]) -> None:
|
||||||
latitude=w.solar.latitude,
|
latitude=w.solar.latitude,
|
||||||
insights=w.solar.insights,
|
insights=w.solar.insights,
|
||||||
)
|
)
|
||||||
uow.plan.save(
|
|
||||||
w.plan,
|
|
||||||
property_id=w.property_id,
|
|
||||||
scenario_id=w.scenario_id,
|
|
||||||
portfolio_id=w.portfolio_id,
|
|
||||||
is_default=w.is_default,
|
|
||||||
)
|
|
||||||
uow.property.mark_modelled(
|
uow.property.mark_modelled(
|
||||||
w.property_id, has_recommendations=w.has_recommendations
|
w.property_id, has_recommendations=w.has_recommendations
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -41,40 +41,9 @@ class PlanPostgresRepository(PlanRepository):
|
||||||
portfolio_id: int,
|
portfolio_id: int,
|
||||||
is_default: bool,
|
is_default: bool,
|
||||||
) -> int:
|
) -> int:
|
||||||
# Soft-replace (ADR-0012): keep prior Plans as history rather than DELETEing
|
return self.save_batch(
|
||||||
# them — the cascade delete of recommendation rows was the slow part. When
|
[PlanSaveRequest(plan, property_id=property_id, scenario_id=scenario_id, portfolio_id=portfolio_id, is_default=is_default)]
|
||||||
# this Plan is the default, demote every prior Plan for the same
|
)[0]
|
||||||
# (property_id, scenario_id) to is_default=False, so exactly one Plan for
|
|
||||||
# the pair stays default (the one just inserted).
|
|
||||||
if is_default:
|
|
||||||
self._session.exec( # type: ignore[call-overload]
|
|
||||||
update(PlanModel)
|
|
||||||
.where(
|
|
||||||
col(PlanModel.property_id) == property_id,
|
|
||||||
col(PlanModel.scenario_id) == scenario_id,
|
|
||||||
)
|
|
||||||
.values(is_default=False)
|
|
||||||
)
|
|
||||||
|
|
||||||
plan_row = PlanModel.from_domain(
|
|
||||||
plan,
|
|
||||||
property_id=property_id,
|
|
||||||
scenario_id=scenario_id,
|
|
||||||
portfolio_id=portfolio_id,
|
|
||||||
is_default=is_default,
|
|
||||||
)
|
|
||||||
self._session.add(plan_row)
|
|
||||||
self._session.flush()
|
|
||||||
if plan_row.id is None:
|
|
||||||
raise ValueError("plan row did not receive an id")
|
|
||||||
|
|
||||||
for measure in plan.measures:
|
|
||||||
self._session.add(
|
|
||||||
RecommendationModel.from_domain(
|
|
||||||
measure, property_id=property_id, plan_id=plan_row.id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return plan_row.id
|
|
||||||
|
|
||||||
def save_batch(self, requests: list[PlanSaveRequest]) -> list[int]:
|
def save_batch(self, requests: list[PlanSaveRequest]) -> list[int]:
|
||||||
"""Persist all Plans in three statements regardless of batch size.
|
"""Persist all Plans in three statements regardless of batch size.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue