Presun nacitani doby letu do dataloaderu

This commit is contained in:
Michal Kváček
2023-10-09 10:24:53 +02:00
parent b355d0b439
commit 86fe3949f6
5 changed files with 46 additions and 30 deletions
@@ -0,0 +1,24 @@
from typing import List
from sqlalchemy import select, func
from strawberry.dataloader import DataLoader
from database import async_session, models
async def load_flight_durations(ids: List[int]):
async with async_session() as db:
flights = (await db.execute(
select(
models.Flight.id,
func.timediff(models.Flight.landing_datetime, models.Flight.takeoff_datetime).label("diff"),
func.coalesce(func.sum(models.FlightTrack.landing_duration), 0).label("landing_duration")
).join(models.Flight.track, isouter=True)
.group_by(models.Flight.id)
.filter(models.Flight.id.in_(ids))
)).all()
items_by_id = {item.id: item.diff.seconds // 60 - item.landing_duration for item in flights}
return [items_by_id.get(id_) for id_ in ids]
flight_duration_dataloader = DataLoader(load_fn=load_flight_durations, cache=False)
-2
View File
@@ -18,8 +18,6 @@ from .resolvers.base import get_base_resolver, get_list
from graphql_schema.entities.types.mutation_input import ComboboxInput from graphql_schema.entities.types.mutation_input import ComboboxInput
@strawberry.type @strawberry.type
class PhotoQueries: class PhotoQueries:
@strawberry.field() @strawberry.field()
@@ -1,12 +1,10 @@
import asyncio import asyncio
from datetime import datetime from datetime import datetime
from typing import List, Optional, Type from typing import List, Optional, Type
from aiocache import cached from aiocache import cached
from sqlalchemy import delete, insert from sqlalchemy import delete, insert
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from strawberry.file_uploads import Upload from strawberry.file_uploads import Upload
from background_jobs.elevation import add_terrain_elevation_to_flight from background_jobs.elevation import add_terrain_elevation_to_flight
from database import models from database import models
from database.models import flight_has_copilot from database.models import flight_has_copilot
@@ -93,7 +91,9 @@ class FlightMutationResolver(BaseMutationResolver):
data['landing_airport_id'] = landing_airport.id data['landing_airport_id'] = landing_airport.id
data['landing_datetime'] = landing_datetime data['landing_datetime'] = landing_datetime
weather_info = await handle_weather_info(db, landing_datetime, landing_airport, flight_data['landing_weather_info_id']) weather_info = await handle_weather_info(
db, landing_datetime, landing_airport, flight_data['landing_weather_info_id']
)
if weather_info: if weather_info:
data['landing_weather_info_id'] = weather_info.id data['landing_weather_info_id'] = weather_info.id
@@ -104,7 +104,9 @@ class FlightMutationResolver(BaseMutationResolver):
data['takeoff_airport_id'] = takeoff_airport.id data['takeoff_airport_id'] = takeoff_airport.id
data['takeoff_datetime'] = takeoff_datetime data['takeoff_datetime'] = takeoff_datetime
weather_info = await handle_weather_info(db, takeoff_datetime, takeoff_airport, flight_data['takeoff_weather_info_id']) weather_info = await handle_weather_info(
db, takeoff_datetime, takeoff_airport, flight_data['takeoff_weather_info_id']
)
if weather_info: if weather_info:
data['takeoff_weather_info_id'] = weather_info.id data['takeoff_weather_info_id'] = weather_info.id
+15 -24
View File
@@ -1,15 +1,22 @@
from __future__ import annotations from __future__ import annotations
from datetime import datetime, timedelta from datetime import datetime
from typing import Optional, Annotated, List from typing import Optional, Annotated, List
import strawberry import strawberry
from sqlalchemy import func, select
from config import API_URL from config import API_URL
from database import models from database import models
from decorators.endpoints import authenticated_user_only from decorators.endpoints import authenticated_user_only
from dependencies.db import get_session
from external.gpx_parser import GPXParser from external.gpx_parser import GPXParser
from graphql_schema.dataloaders.multi_models import poi_photos_dataloader, flight_by_poi_dataloader, flight_copilots_dataloader, flight_track_dataloader, photos_dataloader, flights_by_aircraft_dataloader, users_in_organization_dataloader, aircrafts_from_organization_dataloader, user_organizations_dataloader, flights_by_event_dataloader, flights_by_copilot_dataloader from graphql_schema.dataloaders.flight_duration import flight_duration_dataloader
from graphql_schema.dataloaders.single_model import poi_dataloader, poi_type_dataloader, event_dataloader, aircraft_dataloader, airport_dataloader, cover_photo_loader, airport_weather_info_loader, organizations_dataloader from graphql_schema.dataloaders.multi_models import (
poi_photos_dataloader, flight_by_poi_dataloader, flight_copilots_dataloader, flight_track_dataloader,
photos_dataloader, flights_by_aircraft_dataloader, users_in_organization_dataloader,
aircrafts_from_organization_dataloader, user_organizations_dataloader, flights_by_event_dataloader,
flights_by_copilot_dataloader
)
from graphql_schema.dataloaders.single_model import (
poi_dataloader, poi_type_dataloader, event_dataloader, aircraft_dataloader, airport_dataloader, cover_photo_loader,
airport_weather_info_loader, organizations_dataloader
)
from graphql_schema.entities.airport import Airport from graphql_schema.entities.airport import Airport
from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_type from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_type
from paths import get_photo_basepath from paths import get_photo_basepath
@@ -87,21 +94,6 @@ class GPXTrack:
@strawberry_sqlalchemy_type(models.Flight) @strawberry_sqlalchemy_type(models.Flight)
class Flight: class Flight:
async def duration_min_calculated(root):
# TODO: predelat na dataloader, dobu nacitat v DB
diff: timedelta = root.landing_datetime - root.takeoff_datetime
total_time_minutes = diff.seconds / 60
async with get_session() as db:
landing_durations = (await db.scalars(
select(func.sum(models.FlightTrack.landing_duration))
.filter(models.FlightTrack.airport_id.isnot(None))
.filter(models.FlightTrack.flight_id == root.id)
)).one() or 0
print(landing_durations)
return total_time_minutes - float(landing_durations)
async def load_gpx_track(root): async def load_gpx_track(root):
if not root.gpx_track_filename: if not root.gpx_track_filename:
return None return None
@@ -132,7 +124,6 @@ class Flight:
async def load_event(root): async def load_event(root):
return await event_dataloader.load(root.event_id) return await event_dataloader.load(root.event_id)
duration_min_calculated: int = strawberry.field(resolver=duration_min_calculated)
copilots: Optional[List[Copilot]] = strawberry.field(resolver=load_copilots) copilots: Optional[List[Copilot]] = strawberry.field(resolver=load_copilots)
event: Optional[Event] = strawberry.field(resolver=load_event) event: Optional[Event] = strawberry.field(resolver=load_event)
aircraft: Aircraft = strawberry.field(resolver=lambda root: aircraft_dataloader.load(root.aircraft_id)) aircraft: Aircraft = strawberry.field(resolver=lambda root: aircraft_dataloader.load(root.aircraft_id))
@@ -147,10 +138,10 @@ class Flight:
resolver=lambda root: airport_weather_info_loader.load(root.landing_weather_info_id) resolver=lambda root: airport_weather_info_loader.load(root.landing_weather_info_id)
) )
photos: List[Photo] = strawberry.field(resolver=lambda root: photos_dataloader.load(root.id)) photos: List[Photo] = strawberry.field(resolver=lambda root: photos_dataloader.load(root.id))
gpx_track_url: Optional[str] = strawberry.field(
resolver=lambda root: get_public_url(f"/tracks/{root.gpx_track_filename}") if root.gpx_track_filename else None
) # TODO: odstranit
gpx_track: Optional[GPXTrack] = strawberry.field(resolver=load_gpx_track) gpx_track: Optional[GPXTrack] = strawberry.field(resolver=load_gpx_track)
duration_min_calculated: int = strawberry.field(
resolver=lambda root: flight_duration_dataloader.load(root.id)
)
@strawberry_sqlalchemy_type(models.Copilot) @strawberry_sqlalchemy_type(models.Copilot)
+1
View File
@@ -2,5 +2,6 @@ PHOTO_BASE_PATH = ""
AIRCRAFT_BASE_PATH = "" AIRCRAFT_BASE_PATH = ""
FLIGHT_BASE_PATH = "" FLIGHT_BASE_PATH = ""
def get_photo_basepath(flight_id: int) -> str: def get_photo_basepath(flight_id: int) -> str:
return f"/app/uploads/photos/{flight_id}" return f"/app/uploads/photos/{flight_id}"