Files
api/src/database/models.py
T
2023-06-05 09:55:17 +02:00

241 lines
10 KiB
Python

import datetime
from typing import Set
from sqlalchemy import String, DateTime, ForeignKey, Text, Integer, func, Table, Column, Boolean, select
from sqlalchemy.orm import Mapped, relationship, as_declarative, mapped_column
from database.custom_types import Point
from sqlalchemy.ext.asyncio import AsyncSession
@as_declarative()
class BaseModel:
excluded_columns_in_dict = tuple()
def as_dict(self):
return {
c.name: getattr(self, c.name)
for c in self.__table__.columns
if c.name not in self.excluded_columns_in_dict
}
@classmethod
async def create(cls, db_session: AsyncSession, data: dict):
model = cls(**data)
db_session.add(model)
await db_session.commit()
return model
@classmethod
async def update(cls, db_session: AsyncSession, id: int, data: dict):
obj = (await db_session.scalars(select(cls).filter_by(id=id))).one()
for key, value in data.items():
if getattr(obj, key) != value:
setattr(obj, key, value)
await db_session.commit()
return obj
# TODO: doplnit GPX k letu, pocasi k letu (podle lokality, mozna do FlightTrack)
user_is_in_organization = Table(
"user_is_in_organization",
BaseModel.metadata,
Column("user_id", Integer, ForeignKey("user.id"), primary_key=True),
Column("organization_id", Integer, ForeignKey("organization.id"), primary_key=True)
)
class Airport(BaseModel):
__tablename__ = "airport"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
icao_code: Mapped[str] = mapped_column(String(4), nullable=False)
gps_position: Mapped[Point] = mapped_column(Point, nullable=True)
elevation: Mapped[int] = mapped_column(Integer, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
metars: Mapped['Metar'] = relationship(back_populates="airport")
class PointOfInterestType(BaseModel):
__tablename__ = "point_of_interest_type"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
is_public: Mapped[bool] = mapped_column(Boolean, server_default='0')
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
created_by: Mapped['User'] = relationship()
class PointOfInterest(BaseModel):
__tablename__ = "point_of_interest"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
gps_position: Mapped[Point] = mapped_column(Point, nullable=True)
type_id: Mapped[int] = mapped_column(Integer, ForeignKey("point_of_interest_type.id"))
is_public: Mapped[bool] = mapped_column(Boolean, server_default='0')
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
type: Mapped[PointOfInterestType] = relationship()
created_by: Mapped['User'] = relationship()
class Photo(BaseModel):
__tablename__ = "photo"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
filename: Mapped[str] = mapped_column(String(128), nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False)
gps_position: Mapped[Point] = mapped_column(Point, nullable=True)
flight_id: Mapped[int] = mapped_column(Integer, ForeignKey("flight.id"), nullable=False)
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
flight: Mapped['Flight'] = relationship(back_populates="photos")
created_by: Mapped['User'] = relationship()
class Aircraft(BaseModel):
__tablename__ = "aircraft"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
photo_filename: Mapped[str] = mapped_column(String(128), nullable=True)
manufacturer: Mapped[str] = mapped_column(Text, nullable=False, server_default="")
model: Mapped[str] = mapped_column(String(30), nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False)
organization_id: Mapped[int] = mapped_column(Integer, ForeignKey('organization.id'), nullable=True)
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default='0')
organization: Mapped['Organization'] = relationship()
flights: Mapped[Set['Flight']] = relationship()
created_by: Mapped['User'] = relationship()
notes: Mapped['AircraftNotes'] = relationship()
class AircraftNotes(BaseModel):
__tablename__ = "aircraft_notes"
id: Mapped[int] = mapped_column(primary_key=True)
aircraft_id: Mapped[int] = mapped_column(Integer, ForeignKey("aircraft.id"), nullable=False)
name: Mapped[str] = mapped_column(String(128), nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False)
is_public: Mapped[bool] = mapped_column(Boolean, server_default='0')
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
created_by: Mapped['User'] = relationship()
aircraft: Mapped['Aircraft'] = relationship(back_populates="notes")
class Organization(BaseModel):
__tablename__ = "organization"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
users: Mapped[Set['User']] = relationship(back_populates='organizations', secondary=user_is_in_organization)
created_by: Mapped['User'] = relationship()
class FlightTrack(BaseModel):
__tablename__ = "flight_track"
id: Mapped[int] = mapped_column(primary_key=True)
flight_id: Mapped[int] = mapped_column(Integer, ForeignKey("flight.id"), nullable=False)
poi_id: Mapped[int] = mapped_column(Integer, ForeignKey("point_of_interest.id"), nullable=False)
order: Mapped[int] = mapped_column(Integer)
flight: Mapped['Flight'] = relationship()
point_of_interest: Mapped['PointOfInterest'] = relationship()
class Flight(BaseModel):
__tablename__ = "flight"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False)
takeoff_airport_id: Mapped[int] = mapped_column(Integer, ForeignKey("airport.id"), nullable=True)
landing_airport_id: Mapped[int] = mapped_column(Integer, ForeignKey("airport.id"), nullable=True)
aircraft_id: Mapped[int] = mapped_column(Integer, ForeignKey('aircraft.id'))
copilot_id: Mapped[int] = mapped_column(Integer, ForeignKey('copilot.id'), nullable=True)
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
duration_total: Mapped[int] = mapped_column(Integer, nullable=False)
duration_pic: Mapped[int] = mapped_column(Integer, nullable=False)
takeoff_airport: Mapped['Airport'] = relationship(foreign_keys=[takeoff_airport_id])
landing_airport: Mapped['Airport'] = relationship(foreign_keys=[landing_airport_id])
copilot: Mapped['Copilot'] = relationship(back_populates="flights")
aircraft: Mapped['Aircraft'] = relationship(back_populates="flights")
photos: Mapped[Set['Photo']] = relationship()
user: Mapped['User'] = relationship(back_populates="flights")
created_by: Mapped['User'] = relationship()
# flight_track: Mapped[List['PointOfInterest']] = relationship(secondary=FlightTrack)
class Copilot(BaseModel):
__tablename__ = "copilot"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
flights: Mapped[Set['Flight']] = relationship(back_populates="copilot")
created_by: Mapped['User'] = relationship()
class Metar(BaseModel):
__tablename__ = "metar"
id: Mapped[int] = mapped_column(primary_key=True)
airport_id: Mapped[int] = mapped_column(Integer, ForeignKey('airport.id'))
metar: Mapped[str] = mapped_column(Text, nullable=False)
issued_at: Mapped[datetime] = mapped_column(DateTime)
airport: Mapped['Airport'] = relationship(back_populates="metars")
class License(BaseModel):
__tablename__ = "license"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
number: Mapped[str] = mapped_column(String(30), nullable=False)
valid_until: Mapped[datetime] = mapped_column(DateTime, nullable=False)
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
user: Mapped['User'] = relationship(back_populates="licences")
created_by: Mapped['User'] = relationship()
class User(BaseModel):
__tablename__ = "user"
excluded_columns_in_dict = ('password_hashed',)
id: Mapped[int] = mapped_column(primary_key=True)
email: Mapped[str] = mapped_column(String(128), nullable=False, unique=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
avatar_image_url: Mapped[str] = mapped_column(String(128), nullable=True)
password_hashed: Mapped[str] = mapped_column(String(60), nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
licences: Mapped[Set['License']] = relationship(back_populates="user")
flights: Mapped[Set['Flight']] = relationship(back_populates="user")
organizations: Mapped[Set['Organization']] = relationship(back_populates="users", secondary=user_is_in_organization)