Model/tests/repositories/solar/test_solar_repository.py
Jun-te Kim de5e9a2362 perf(modelling_e2e): bulk reads and batch writes to cut RDS load
The handler fired ~2+2N read round-trips and N+N write transactions per
SQS batch, pinning RDS CPU under ~32 concurrent containers on pool_size=1.

Reads: merge the duplicate property query and add overrides_for_many /
SolarRepository.get_many so overrides, solar, and property rows each load
in one query (2+2N -> 3).

Writes: buffer each modelled property's persistence intent in memory
(_PropertyWrite) during the loop, then flush the whole batch in one
PostgresUnitOfWork with a single commit, and run the baseline orchestrator
once for all written ids (N+N -> 2 transactions). Per-property modelling
failures stay isolated in the loop; the batch write is all-or-nothing and
retried via SQS (saves are idempotent upserts).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 18:43:42 +00:00

63 lines
2 KiB
Python

"""SolarRepo round-trips Google Solar building insights for a Property."""
from __future__ import annotations
from typing import Any
from sqlalchemy import Engine
from sqlmodel import Session
from repositories.solar.solar_postgres_repository import SolarPostgresRepository
def test_building_insights_round_trip(db_engine: Engine) -> None:
# Arrange
insights: dict[str, Any] = {
"name": "buildings/ChIJ",
"solarPotential": {
"maxArrayPanelsCount": 42,
"panelCapacityWatts": 250.0,
"roofSegmentStats": [{"pitchDegrees": 30.0, "azimuthDegrees": 180.0}],
},
}
# Act
with Session(db_engine) as session:
SolarPostgresRepository(session).save(
5, longitude=-0.1, latitude=51.5, insights=insights
)
session.commit()
with Session(db_engine) as session:
reloaded = SolarPostgresRepository(session).get(5)
# Assert
assert reloaded == insights
def test_get_returns_none_when_no_insights_stored(db_engine: Engine) -> None:
# Arrange / Act
with Session(db_engine) as session:
reloaded = SolarPostgresRepository(session).get(999)
# Assert
assert reloaded is None
def test_get_many_returns_entry_for_every_requested_uprn(db_engine: Engine) -> None:
"""get_many reads many UPRNs in one query: stored UPRNs return their
insights, unstored ones map to None, and every requested UPRN is present."""
# Arrange
insights_10: dict[str, Any] = {"name": "buildings/A"}
insights_20: dict[str, Any] = {"name": "buildings/B"}
with Session(db_engine) as session:
repo = SolarPostgresRepository(session)
repo.save(10, longitude=-0.1, latitude=51.5, insights=insights_10)
repo.save(20, longitude=-0.2, latitude=52.0, insights=insights_20)
session.commit()
# Act — 30 has no stored row
with Session(db_engine) as session:
loaded = SolarPostgresRepository(session).get_many([10, 20, 30])
# Assert
assert loaded == {10: insights_10, 20: insights_20, 30: None}