Presun nacitani doby letu do dataloaderu
This commit is contained in:
@@ -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)
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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}"
|
||||||
|
|||||||
Reference in New Issue
Block a user