Учебный ресурс кафедры физики твёрдого тела ФТИ ПетрГУ

Python + PostgreSQL + SQLAlchemy

# организуем доступ к методам sqlalchemy
from sqlalchemy import create_engine, func
from sqlalchemy import Column, ForeignKey, Integer, String, DateTime, JSON, CheckConstraint
from sqlalchemy.orm import declarative_base, sessionmaker
from prettytable import PrettyTable

# создаем некоторые классы, которые будут отображаться в структуру базы данных
Base = declarative_base()

# модели самолётов
class Aircrafts(Base):
__tablename__='aircrafts'
aircraft=Column(Integer, primary_key=True, name='aircraft_code')
model=Column(JSON)
range=Column(Integer)

# количество и категории посадочных мест
class Seats(Base):
__tablename__='seats'
__table_args__= (CheckConstraint("fare_conditions in ('Business', 'Economy', 'Comfort')"),)
aircraft=Column(Integer, ForeignKey('aircrafts.aircraft_code'), primary_key=True, name='aircraft_code')
seat_no=Column(Integer, primary_key=True)
fare_conditions=Column(String)

# соединяемся с базой данных и "создаём" её структуру
ds = "postgresql://demo:<fpsLfyys[Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.:5432/demo"
db = create_engine(ds)
Base.metadata.create_all(db)

###

Session = sessionmaker(db)
s = Session()

seatList = []
resp = input("Какие категории мест ищем? 1 - Business, 2 - Economy, 3 - Comfort --> ")
if resp.find('1') != -1: seatList.append('Business')
if resp.find('2') != -1: seatList.append('Economy')
if resp.find('3') != -1: seatList.append('Comfort')
print(f'Для выбранных категорий мест: {seatList} найдено:')
res = s.query(Aircrafts.aircraft,
func.max(Aircrafts.model).label('model'),
func.max(Aircrafts.range).label('range'),
func.count(Seats.seat_no).label('seats')).outerjoin(Seats).filter(
Seats.fare_conditions.in_(seatList)
).group_by(Aircrafts.aircraft).all()
table = PrettyTable(['Самолёт', 'Модель', 'Дальность', 'Число мест'])
for r in res:
table.add_row([r.aircraft, r.model, r.range, r.seats])
print(table)
 

Вывод программы:
 
Какие категории мест ищем? 1 - Business, 2 - Economy, 3 - Comfort --> 1   
Для выбранных категорий мест: ['Business'] найдено:
+---------+---------------------+-----------+------------+
| Самолёт |        Модель       | Дальность | Число мест |
+---------+---------------------+-----------+------------+
|   320   |   Аэробус A320-200  |    5700   |     20     |
|   773   |    Боинг 777-300    |   11100   |     30     |
|   763   |    Боинг 767-300    |    7900   |     30     |
|   319   |   Аэробус A319-100  |    6700   |     20     |
|   733   |    Боинг 737-300    |    4200   |     12     |
|   SU9   | Сухой Суперджет-100 |    3000   |     12     |
|   321   |   Аэробус A321-200  |    5600   |     28     |
+---------+---------------------+-----------+------------+