Priprava modelu na GPX v DB

This commit is contained in:
Michal Kváček
2024-06-24 16:22:50 +02:00
parent 2bf737b9d6
commit ac3b496459
8 changed files with 139 additions and 23 deletions
@@ -0,0 +1,28 @@
"""add flight_plan.description
Revision ID: a3e1f1a37899
Revises: 8a67af3909aa
Create Date: 2024-06-11 16:46:29.786830
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'a3e1f1a37899'
down_revision = '8a67af3909aa'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('flight_plan', sa.Column('description', sa.Text(), server_default='', nullable=False))
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('flight_plan', 'description')
# ### end Alembic commands ###
@@ -0,0 +1,54 @@
"""add track to flight
Revision ID: f9e1e8a01683
Revises: a3e1f1a37899
Create Date: 2024-06-24 16:08:01.084570
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = 'f9e1e8a01683'
down_revision = 'a3e1f1a37899'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('track',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('bounds', mysql.JSON(), nullable=False),
sa.Column('created_by_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('track_point',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('timestamp', sa.DateTime(), nullable=False),
sa.Column('track_id', sa.Integer(), nullable=False),
sa.Column('gps_latitude', sa.Float(), nullable=False),
sa.Column('gps_longitude', sa.Float(), nullable=False),
sa.Column('elevation', sa.Float(), nullable=True),
sa.ForeignKeyConstraint(['track_id'], ['track.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.add_column('flight', sa.Column('track_id', sa.Integer(), nullable=True))
op.create_foreign_key(None, 'flight', 'track', ['track_id'], ['id'])
op.add_column('flight_plan', sa.Column('track_id', sa.Integer(), nullable=True))
op.create_foreign_key(None, 'flight_plan', 'track', ['track_id'], ['id'])
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'flight_plan', type_='foreignkey')
op.drop_column('flight_plan', 'track_id')
op.drop_constraint(None, 'flight', type_='foreignkey')
op.drop_column('flight', 'track_id')
op.drop_table('track_point')
op.drop_table('track')
# ### end Alembic commands ###
+2 -1
View File
@@ -74,7 +74,6 @@ copilot_has_photo = Table(
Column("photo_id", ForeignKey("photo.id"), primary_key=True), Column("photo_id", ForeignKey("photo.id"), primary_key=True),
) )
airport_has_reporting_point = Table( airport_has_reporting_point = Table(
"airport_has_reporting_point", "airport_has_reporting_point",
BaseModel.metadata, BaseModel.metadata,
@@ -105,6 +104,7 @@ class FlightPlan(BaseModel):
is_default_name: Mapped[bool] = mapped_column(Boolean, server_default='0') is_default_name: Mapped[bool] = mapped_column(Boolean, server_default='0')
is_public: Mapped[bool] = mapped_column(Boolean, server_default='0') is_public: Mapped[bool] = mapped_column(Boolean, server_default='0')
is_editable_by_copilot: Mapped[bool] = mapped_column(Boolean, server_default='0') is_editable_by_copilot: Mapped[bool] = mapped_column(Boolean, server_default='0')
description: Mapped[str] = mapped_column(Text, nullable=False, server_default="")
planned_speed: Mapped[int] = mapped_column(Integer, nullable=False, default=150) planned_speed: Mapped[int] = mapped_column(Integer, nullable=False, default=150)
planned_takeoff_datetime: Mapped[datetime] = mapped_column(DateTime, nullable=True) planned_takeoff_datetime: Mapped[datetime] = mapped_column(DateTime, nullable=True)
aircraft_id: Mapped[int] = mapped_column(Integer, ForeignKey("aircraft.id"), nullable=True) aircraft_id: Mapped[int] = mapped_column(Integer, ForeignKey("aircraft.id"), nullable=True)
@@ -130,6 +130,7 @@ class FlightPlanMarker(BaseModel):
gps_longitude: Mapped[float] = mapped_column(Float, nullable=False) gps_longitude: Mapped[float] = mapped_column(Float, nullable=False)
weather_info_id: Mapped[int] = mapped_column(Integer, ForeignKey('weather_info.id'), nullable=True) weather_info_id: Mapped[int] = mapped_column(Integer, ForeignKey('weather_info.id'), nullable=True)
class Airport(BaseModel): class Airport(BaseModel):
__tablename__ = "airport" __tablename__ = "airport"
+1 -1
View File
@@ -11,7 +11,7 @@ from graphql_schema.entities.types.types import Airport
class AirportQueries: class AirportQueries:
@strawberry.field() @strawberry.field()
@error_logging @error_logging
@authenticated_user_only() # @authenticated_user_only()
async def airports(root, info) -> List[Airport]: async def airports(root, info) -> List[Airport]:
return await BaseQueryResolver(Airport, models.Airport).get_list(info.context.user_id) return await BaseQueryResolver(Airport, models.Airport).get_list(info.context.user_id)
+19 -9
View File
@@ -1,11 +1,10 @@
from typing import List from typing import List, Optional
import strawberry import strawberry
from strawberry.types import Info from strawberry.types import Info
from database import models
from decorators.error_logging import error_logging
from decorators.endpoints import authenticated_user_only, allow_public from decorators.endpoints import authenticated_user_only, allow_public
from graphql_schema.entities.resolvers.base import BaseQueryResolver from decorators.error_logging import error_logging
from graphql_schema.entities.resolvers.flight_plan import FlightPlanMutationResolver from graphql_schema.entities.helpers.detail import get_detail_filters
from graphql_schema.entities.resolvers.flight_plan import FlightPlanMutationResolver, FlightPlanQueryResolver
from graphql_schema.entities.types.mutation_input import CreateFlightPlanInput, EditFlightPlanInput from graphql_schema.entities.types.mutation_input import CreateFlightPlanInput, EditFlightPlanInput
from graphql_schema.entities.types.types import FlightPlan from graphql_schema.entities.types.types import FlightPlan
@@ -16,15 +15,26 @@ class FlightPlanQueries:
@error_logging @error_logging
@authenticated_user_only() @authenticated_user_only()
async def flight_plans(root, info: Info) -> List[FlightPlan]: async def flight_plans(root, info: Info) -> List[FlightPlan]:
return await BaseQueryResolver(FlightPlan, models.FlightPlan).get_list(info.context.user_id) return await FlightPlanQueryResolver().get_list(info.context.user_id)
@strawberry.field() @strawberry.field()
@error_logging @error_logging
@allow_public @allow_public
async def flight_plan(root, info: Info, id: int) -> FlightPlan: async def flight_plan(
return await BaseQueryResolver(FlightPlan, models.FlightPlan).get_one( root,
info: Info,
id: int,
username: Optional[str] = None,
public: Optional[bool] = False
) -> FlightPlan:
filter_params = get_detail_filters(id)
if username:
filter_params['username'] = username
return await FlightPlanQueryResolver().get_one(
user_id=info.context.user_id, user_id=info.context.user_id,
object_id=id only_public=public,
**filter_params
) )
@@ -2,7 +2,7 @@ from typing import Optional
from graphql import GraphQLError from graphql import GraphQLError
def get_detail_filters(id: Optional[int], url_slug: Optional[str]) -> dict: def get_detail_filters(id: Optional[int] = None, url_slug: Optional[str] = None) -> dict:
filter_params = {} filter_params = {}
if id: if id:
filter_params['object_id'] = id filter_params['object_id'] = id
@@ -28,17 +28,11 @@ class FlightQueryResolver(BaseQueryResolver):
def get_query( def get_query(
self, self,
user_id: Optional[int] = None, user_id: Optional[int] = None,
object_id: Optional[int] = None,
url_slug: Optional[str] = None,
only_public: Optional[bool] = False, only_public: Optional[bool] = False,
*args, *args,
**kwargs **kwargs
): ):
filters = {} filters = {key: kwargs[key] for key in ("object_id", "url_slug") if key in kwargs}
if object_id:
filters['object_id'] = object_id
if url_slug:
filters['url_slug'] = url_slug
query = super().get_query( query = super().get_query(
user_id, user_id,
@@ -1,19 +1,48 @@
import asyncio import asyncio
from typing import Optional
from sqlalchemy import delete, select from sqlalchemy import delete, select
from sqlalchemy.dialects.mysql import insert from sqlalchemy.dialects.mysql import insert
from database import models from database import models
from database.models import flight_plan_has_copilot from database.models import flight_plan_has_copilot
from database.transaction import get_session from database.transaction import get_session
from graphql_schema.entities.helpers.combobox import handle_combobox_save from graphql_schema.entities.helpers.combobox import handle_combobox_save
from graphql_schema.entities.resolvers.base import BaseMutationResolver from graphql_schema.entities.resolvers.base import BaseMutationResolver, BaseQueryResolver
from graphql_schema.entities.resolvers.flight import handle_aircraft_save from graphql_schema.entities.resolvers.flight import handle_aircraft_save
from graphql_schema.entities.types.mutation_input import CreateFlightPlanInput, EditFlightPlanInput from graphql_schema.entities.types.mutation_input import CreateFlightPlanInput, EditFlightPlanInput
from graphql_schema.entities.types.types import FlightPlan from graphql_schema.entities.types.types import FlightPlan
from utils.str_utils import random_str from utils.str_utils import random_str
class FlightPlanQueryResolver(BaseQueryResolver):
def __init__(self):
super().__init__(graphql_type=FlightPlan, model=models.FlightPlan)
def get_query(
self,
user_id: Optional[int] = None,
only_public: Optional[bool] = False,
object_id: Optional[int] = None,
*args,
**kwargs
):
filters = {"object_id": object_id} if object_id else {}
query = super().get_query(
user_id,
**filters,
order_by=[models.FlightPlan.planned_takeoff_datetime.desc(), models.FlightPlan.id.desc()],
only_public=only_public,
only_my=not only_public
)
if kwargs.get('username'):
query = (
query.join(models.FlightPlan.created_by)
.filter(models.User.public_username == kwargs['username'])
)
return query
class FlightPlanMutationResolver(BaseMutationResolver): class FlightPlanMutationResolver(BaseMutationResolver):
def __init__(self): def __init__(self):
super().__init__(graphql_type=FlightPlan, model=models.FlightPlan) super().__init__(graphql_type=FlightPlan, model=models.FlightPlan)