|
11 | 11 | from sqlalchemy import desc
|
12 | 12 | from sqlalchemy.orm import contains_eager, joinedload
|
13 | 13 | from sqlalchemy.orm.session import Session
|
14 |
| -from sqlalchemy.sql.expression import false, true |
15 | 14 |
|
| 15 | +from nowcasting_datamodel import N_GSP |
16 | 16 | from nowcasting_datamodel.models import (
|
17 | 17 | ForecastSQL,
|
18 | 18 | ForecastValueLatestSQL,
|
@@ -138,36 +138,14 @@ def get_latest_forecast(
|
138 | 138 |
|
139 | 139 | logger.debug(f"Getting latest forecast for gsp {gsp_id}")
|
140 | 140 |
|
141 |
| - # start main query |
142 |
| - query = session.query(ForecastSQL) |
143 |
| - order_by_items = [] |
144 |
| - |
145 |
| - if historic: |
146 |
| - query = query.filter(ForecastSQL.historic == true()) |
147 |
| - else: |
148 |
| - query = query.filter(ForecastSQL.historic == false()) |
149 |
| - |
150 |
| - if start_target_time is not None: |
151 |
| - query = filter_query_on_target_time( |
152 |
| - query=query, start_target_time=start_target_time, historic=historic |
153 |
| - ) |
154 |
| - |
155 |
| - # filter on gsp_id |
156 | 141 | if gsp_id is not None:
|
157 |
| - query = query.join(LocationSQL) |
158 |
| - query = query.filter(LocationSQL.gsp_id == gsp_id) |
159 |
| - order_by_items.append(LocationSQL.gsp_id) |
160 |
| - |
161 |
| - order_by_items.append(ForecastSQL.created_utc.desc()) |
162 |
| - if not historic: |
163 |
| - created_utc = get_latest_forecast_created_utc(session=session, gsp_id=gsp_id) |
164 |
| - query = query.filter(ForecastSQL.created_utc == created_utc) |
165 |
| - |
166 |
| - # this make the newest ones comes to the top |
167 |
| - query = query.order_by(*order_by_items) |
| 142 | + gsp_ids = [gsp_id] |
| 143 | + else: |
| 144 | + gsp_ids = None |
168 | 145 |
|
169 |
| - # get all results |
170 |
| - forecasts = query.all() |
| 146 | + forecasts = get_latest_forecast_for_gsps( |
| 147 | + session=session, start_target_time=start_target_time, historic=historic, gsp_ids=gsp_ids |
| 148 | + ) |
171 | 149 |
|
172 | 150 | if forecasts is None:
|
173 | 151 | return None
|
@@ -213,35 +191,84 @@ def get_all_gsp_ids_latest_forecast(
|
213 | 191 |
|
214 | 192 | logger.debug("Getting latest forecast for all gsps")
|
215 | 193 |
|
| 194 | + return get_latest_forecast_for_gsps( |
| 195 | + session=session, |
| 196 | + start_created_utc=start_created_utc, |
| 197 | + start_target_time=start_target_time, |
| 198 | + preload_children=preload_children, |
| 199 | + historic=historic, |
| 200 | + gsp_ids=list(range(0, N_GSP + 1)), |
| 201 | + ) |
| 202 | + |
| 203 | + |
| 204 | +def get_latest_forecast_for_gsps( |
| 205 | + session: Session, |
| 206 | + start_created_utc: Optional[datetime] = None, |
| 207 | + start_target_time: Optional[datetime] = None, |
| 208 | + preload_children: Optional[bool] = False, |
| 209 | + historic: bool = False, |
| 210 | + gsp_ids: List[int] = None, |
| 211 | +): |
| 212 | + """ |
| 213 | + Read forecasts |
| 214 | +
|
| 215 | + :param session: database session |
| 216 | + :param start_created_utc: Filter: forecast creation time should be larger than this datetime |
| 217 | + :param start_target_time: |
| 218 | + Filter: forecast values target time should be larger than this datetime |
| 219 | + :param preload_children: Option to preload children. This is a speed up, if we need them. |
| 220 | + :param historic: Option to load historic values or not |
| 221 | + :param gsp_ids: Option to filter on gsps. If None, then only the lastest forecast is loaded. |
| 222 | +
|
| 223 | + return: List of forecasts objects from database |
| 224 | +
|
| 225 | + :param session: |
| 226 | + :param start_created_utc: |
| 227 | + :param start_target_time: |
| 228 | + :param preload_children: |
| 229 | + :param historic: |
| 230 | + :param gsp_ids: |
| 231 | + :return: |
| 232 | + """ |
| 233 | + order_by_cols = [] |
| 234 | + |
216 | 235 | # start main query
|
217 | 236 | query = session.query(ForecastSQL)
|
218 | 237 |
|
| 238 | + # filter on created_utc |
219 | 239 | if start_created_utc is not None:
|
220 | 240 | query = query.filter(ForecastSQL.created_utc >= start_created_utc)
|
221 | 241 |
|
222 |
| - # join with tables |
223 |
| - if not historic: |
224 |
| - query = query.distinct(LocationSQL.gsp_id) |
| 242 | + # join with location table and filter |
| 243 | + if gsp_ids is not None: |
| 244 | + if not historic: |
| 245 | + # for historic they are already distinct |
| 246 | + query = query.distinct(LocationSQL.gsp_id) |
| 247 | + query = query.filter(LocationSQL.gsp_id.in_(gsp_ids)) |
| 248 | + order_by_cols.append(LocationSQL.gsp_id) |
225 | 249 | query = query.join(LocationSQL)
|
226 | 250 |
|
| 251 | + # filter on historic |
227 | 252 | query = query.filter(ForecastSQL.historic == historic)
|
228 | 253 |
|
| 254 | + # filter on target time |
229 | 255 | if start_target_time is not None:
|
230 | 256 | query = filter_query_on_target_time(
|
231 | 257 | query=query, start_target_time=start_target_time, historic=historic
|
232 | 258 | )
|
233 | 259 |
|
| 260 | + # option to preload values, makes querying quicker |
234 | 261 | if preload_children:
|
235 | 262 | query = query.options(joinedload(ForecastSQL.location))
|
236 | 263 | query = query.options(joinedload(ForecastSQL.model))
|
237 | 264 | query = query.options(joinedload(ForecastSQL.input_data_last_updated))
|
238 | 265 | if not historic:
|
239 | 266 | query = query.options(joinedload(ForecastSQL.forecast_values))
|
240 |
| - query = query.options(joinedload(ForecastSQL.forecast_values_latest)) |
241 | 267 |
|
242 |
| - query = query.order_by(LocationSQL.gsp_id, desc(ForecastSQL.created_utc)) |
| 268 | + order_by_cols.append(desc(ForecastSQL.created_utc)) |
| 269 | + query = query.order_by(*order_by_cols) |
243 | 270 |
|
244 |
| - forecasts = query.populate_existing().all() |
| 271 | + forecasts = query.all() |
245 | 272 |
|
246 | 273 | logger.debug(f"Found {len(forecasts)} forecasts")
|
247 | 274 | if len(forecasts) > 0:
|
|
0 commit comments