mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
feat(modelling): cut plan→recommendation readers onto plan_id
Rewrite the three structurally-identical m2m-join readers (portfolio_functions.aggregate_portfolio_recommendations, Outputs.get_recommendations_from_db, export get_recommendations) to join PlanModel directly via recommendation.plan_id, dropping the plan_recommendations join and its now-unused import. The writers set plan_id (prior slice), so the rows resolve. test_export pins the export reader through the cut (its fixtures now set recommendation.plan_id). A portfolio_functions DB characterization test lands with the scenario consolidation (which provides the full-parity scenario table the aggregation writes to). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
27fcc5b184
commit
af5dbe325d
4 changed files with 14 additions and 24 deletions
|
|
@ -11,7 +11,6 @@ from backend.app.db.models.portfolio import PropertyModel, PropertyDetailsEpcMod
|
|||
from backend.app.db.models.recommendations import (
|
||||
Recommendation,
|
||||
PlanModel,
|
||||
PlanRecommendations,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -124,20 +123,15 @@ class Outputs:
|
|||
return plans_data
|
||||
|
||||
def get_recommendations_from_db(self, plan_ids):
|
||||
# Get recommendations through PlanRecommendations for those plans and that are default
|
||||
# Get default recommendations for those plans, linked by recommendation.plan_id
|
||||
recommendations_query = (
|
||||
self.session.query(Recommendation, PlanModel.scenario_id)
|
||||
.join(
|
||||
PlanRecommendations,
|
||||
Recommendation.id == PlanRecommendations.recommendation_id,
|
||||
)
|
||||
.join(
|
||||
PlanModel,
|
||||
PlanModel.id
|
||||
== PlanRecommendations.plan_id, # Join with Plan to access scenario_id
|
||||
PlanModel.id == Recommendation.plan_id, # access scenario_id
|
||||
)
|
||||
.filter(
|
||||
PlanRecommendations.plan_id.in_(plan_ids),
|
||||
Recommendation.plan_id.in_(plan_ids),
|
||||
Recommendation.default == True, # Filtering for default recommendations
|
||||
)
|
||||
.all()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from sqlalchemy import func
|
||||
from backend.app.db.models.recommendations import (
|
||||
PlanModel,
|
||||
PlanRecommendations,
|
||||
Recommendation,
|
||||
ScenarioModel,
|
||||
)
|
||||
|
|
@ -26,11 +25,7 @@ def aggregate_portfolio_recommendations(
|
|||
),
|
||||
func.sum(Recommendation.energy_cost_savings).label("energy_cost_savings"),
|
||||
)
|
||||
.join(
|
||||
PlanRecommendations,
|
||||
PlanRecommendations.recommendation_id == Recommendation.id,
|
||||
)
|
||||
.join(PlanModel, PlanModel.id == PlanRecommendations.plan_id)
|
||||
.join(PlanModel, PlanModel.id == Recommendation.plan_id)
|
||||
.filter(
|
||||
PlanModel.portfolio_id == portfolio_id,
|
||||
PlanModel.scenario_id == scenario_id,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ from collections import defaultdict
|
|||
from backend.app.db.models.recommendations import (
|
||||
Recommendation,
|
||||
PlanModel,
|
||||
PlanRecommendations,
|
||||
RecommendationMaterials,
|
||||
)
|
||||
from backend.app.db.models.portfolio import (
|
||||
|
|
@ -157,13 +156,9 @@ class DbMethods:
|
|||
|
||||
stmt = (
|
||||
select(Recommendation, PlanModel.scenario_id, PlanModel.name)
|
||||
.join(
|
||||
PlanRecommendations,
|
||||
Recommendation.id == PlanRecommendations.recommendation_id,
|
||||
)
|
||||
.join(PlanModel, PlanModel.id == PlanRecommendations.plan_id)
|
||||
.join(PlanModel, PlanModel.id == Recommendation.plan_id)
|
||||
.where(
|
||||
PlanRecommendations.plan_id.in_(plan_ids),
|
||||
Recommendation.plan_id.in_(plan_ids),
|
||||
Recommendation.default.is_(True),
|
||||
Recommendation.already_installed.is_(False),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -171,13 +171,17 @@ def test_default_export_integration(db_session):
|
|||
# 5) Insert recommendation
|
||||
# ----------------------------------------
|
||||
|
||||
rec_to_plan = dict(
|
||||
zip(plan_recs_df["recommendation_id"], plan_recs_df["plan_id"])
|
||||
)
|
||||
recs = [
|
||||
Recommendation(
|
||||
plan_id=rec_to_plan.get(row["id"]),
|
||||
**{
|
||||
col: row[col]
|
||||
for col in Recommendation.__table__.columns.keys()
|
||||
if col in row
|
||||
}
|
||||
if col in row and col != "plan_id"
|
||||
},
|
||||
)
|
||||
for _, row in recommendations_df.iterrows()
|
||||
]
|
||||
|
|
@ -607,9 +611,11 @@ def test_solar_with_battery_example(db_session):
|
|||
# -------------------------------------------------
|
||||
recommendations_df.loc[0, "measure_type"] = "solar_pv"
|
||||
|
||||
rec_to_plan = dict(zip(plan_recs_df.recommendation_id, plan_recs_df.plan_id))
|
||||
for row in recommendations_df.itertuples(index=False):
|
||||
rec = Recommendation(
|
||||
id=row.id,
|
||||
plan_id=rec_to_plan.get(row.id),
|
||||
property_id=row.property_id,
|
||||
measure_type=row.measure_type,
|
||||
estimated_cost=row.estimated_cost,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue