Задача курса
FastAPI и связь таблиц: бронирования одной комнаты
Курс «FastAPI для начинающих: API с базой данных и тестами» · урок «Переговорная и бронирование: связь таблиц»
Условие
Бронирования выбранной переговорной
Roomly хранит комнаты и связанные с ними бронирования. Реализуйте получение бронирований одной комнаты: в ответ не должны попадать записи других комнат.
Если комната существует, но бронирований у неё нет, верните пустой список. Если самой комнаты нет, верните ошибку отсутствия комнаты. Это разные ситуации, и клиент должен различать их по ответу API.
В этой задаче у бронирования есть только идентификатор и ссылка на комнату. Пользователей, времени встреч и проверки пересечений пока нет. Получение списка не должно менять сохранённые записи.
Что уже дано
В одном видимом файле дан самостоятельный сокращённый SQLAlchemy-проект: Room(id/name/capacity), Booking(id/room_id), настоящий ForeignKey, обе relationship, схемы, настройка SQLite с foreign_keys, Session на запрос и готовый CRUD комнат. POST бронирования уже работает, DELETE комнаты с бронированиями уже защищён409. TODO только в GET списка бронирований. Это не задача на пользователей, время или проверку пересечений.
Перед видимым файлом служебная подготовка создаёт пустой временный каталог внутри рабочей папки и задаёт DATABASE_URL: str — SQLite URL собственного файла roomly.db. Используйте именно это имя; создавать путь или открывать прежние базы не нужно. Публичный переходник выполняет HTTP через TestClient, передаёт диагностические наблюдения и читает этот же файл отдельным SQLite-соединением. Данные для проверок поступают через RPC, ожидаемые ответы в переходнике отсутствуют. После проверки он закрывает свои ресурсы и удаляет только собственный временный каталог. Писать переходник, SQL-диагностику, управление файлами или тесты не требуется. Переходник может получить фактические метаданные связи и проверить FK отдельной диагностической записью в собственную базу с откатом при отказе. Конфигурация связи дана; писать эту диагностику не требуется.
Что нужно сделать
Реализуйте GET /api/rooms/{room_id}/bookings через предоставленную Session. Для существующей комнаты верните200 и список только её бронирований по возрастанию Booking.id. Публичная запись содержит ровно id и room_id. У комнаты без бронирований список пуст; если самой комнаты нет —404/{"detail":"Room not found"}.
room_id берётся из пути; одноимённый query не заменяет его. Неверный тип path получает стандартный422. Идентификатор самого Booking не является идентификатором комнаты. Чтение не добавляет, не удаляет и не меняет никакие строки; последующие новые бронирования должны появляться в соответствующем списке.
Сохраните готовую связь и обработчики: POST на том же пути без тела создаёт связь и отвечает201, неизвестная комната получает404; DELETE занятой комнаты возвращает409/{"detail":"Room has bookings"} без удаления, свободной —204 без тела. Эти действия уже реализованы и не являются дополнительными TODO. Способ фильтрации выбираете вы; JOIN или обход relationship не обязательны.
Ввод и вывод
stdin не используется. Печатать через print в stdout ничего не нужно. После выполнения файла проверяющая система обращается к верхнеуровневому app: публичный переходник вызывает TestClient внутри процесса приложения и передаёт результат скрытой проверке. Запускать Uvicorn, сеть, клиентский скрипт или pytest не требуется.
Если Booking7 принадлежит Room3, а Booking9 — Room8, запрос /api/rooms/3/bookings возвращает только {"id":7,"room_id":3} внутри списка. Для существующей комнаты без записей ответ []; для отсутствующей комнаты —404.
