Engine, Session и база SQLite
Содержание курса
0 / 1 баллов
Сессия для каждого обращения
Roomly занимается управлением переговорными комнатами и до недавнего времени хранила весь каталог прямо в памяти приложения. Теперь команда готовится перенести эти данные в полноценное хранилище и для начала закладывает правильный фундамент: нужно убедиться, что соединение с хранилищем открывается, используется и закрывается так, как этого требует работа с реальными ресурсами.
Главный принцип, который команда хочет соблюсти, прост: каждое обращение к системе должно работать со своей собственной сессией. Никакой общей сессии, которую все запросы делят между собой и которая рано или поздно оказывается в непредсказуемом состоянии. Сессия открывается в начале обработки, сопровождает её до конца и затем аккуратно освобождает занятые ресурсы — независимо от того, завершилось ли обращение успехом или привело к ошибке.
Особенно важно последнее: сбой в одном обращении не должен оставлять за собой незакрытых ресурсов и тем более мешать тем обращениям, которые придут следом. Это требование звучит очевидно, но именно оно чаще всего нарушается, когда освобождение ресурсов доверяют случаю. Отдельного внимания заслуживает и повторная инициализация хранилища: если данные в нём уже есть, они должны остаться нетронутыми.
Результат, к которому стремится команда, — это работающая обвязка вокруг хранилища, которая ведёт себя предсказуемо при любом исходе: сессия появляется тогда, когда нужна, и исчезает, когда её работа закончена.
Что уже дано
Это отдельная однофайловая лаба настройки SQLAlchemy, а не перенос полного Roomly. В редакторе уже есть Base, модель Room(id, name, capacity), app и два законченных диагностических маршрута. Они выполняют предоставленные SQL-операции; писать запросы к строкам самостоятельно в этом уроке не нужно. TODO относятся только к Engine, фабрике и жизненному циклу Session.
Перед видимым файлом служебная подготовка создаёт пустой временный каталог внутри рабочей папки и задаёт DATABASE_URL: str — SQLite URL собственного файла roomly.db. Используйте именно это имя; создавать путь или открывать прежние базы не нужно. Публичный переходник выполняет HTTP через TestClient, передаёт диагностические наблюдения и читает этот же файл отдельным SQLite-соединением. Данные для проверок поступают через RPC, ожидаемые ответы в переходнике отсутствуют. После проверки он закрывает свои ресурсы и удаляет только собственный временный каталог. Писать переходник, SQL-диагностику, управление файлами или тесты не требуется. Наблюдатель удерживает ссылки на выданные Session, их соединения и загруженные ORM-объекты, чтобы проверить освобождение после успеха и после преднамеренного исключения. Он не выдаёт и не закрывает Session вместо вашей get_db во время запросов.
Что нужно сделать
Создайте публичный engine для DATABASE_URL и SessionLocal через sessionmaker: каждый вызов фабрики даёт отдельную Session, связанную с engine; autoflush=False, обычный режим без autocommit. Для файловой SQLite SQLAlchemy2 допускает как явный check_same_thread=False, так и его стандартное значение.
Реализуйте init_db(): она создаёт отсутствующие таблицы зарегистрированного Base и сохраняет существующие строки при повторном вызове. Готовый вызов внизу выполняет инициализацию при запуске. Реализуйте get_db() как зависимость с yield: новая Session остаётся рабочей в течение каждого обработчика и обязательно закрывается после его завершения, в том числе при исключении. Не используйте общую Session для нескольких обращений. Способ гарантированного закрытия выбираете вы.
Сохраните готовые app, модель и обработчики. GET /db-check возвращает200 с status="ok" и числом строк комнаты; GET /db-failure после обращения к той же базе преднамеренно возвращает500 с detail="Intentional diagnostic failure". Следующий запрос должен снова получить свою рабочую Session. Эти диагностические ответы уже реализованы и не являются задачей на их форматирование.
Ввод и вывод
stdin не используется. Печатать через print в stdout ничего не нужно. После выполнения файла проверяющая система обращается к верхнеуровневому app: публичный переходник вызывает TestClient внутри процесса приложения и передаёт результат скрытой проверке. Запускать Uvicorn, сеть, клиентский скрипт или pytest не требуется.
Если в собственной учебной таблице две комнаты, GET /db-check возвращает {"status":"ok","room_count":2}. После GET /db-failure новый успешный запрос видит те же две комнаты; повтор init_db не очищает таблицу.
О данных в ответах
Используйте учебные данные. Не вставляйте пароли, токены, ключи доступа, паспортные и банковские данные, а также персональные данные других людей. Политика обработки данных.
Как проверяется решение
Проверяются функции и их результаты. Собственный запуск выполняет ваш код без авторских тестов. Интерактивный запуск не влияет на оценку. Лимит сессии — 5 минут, процессорного времени — 10 секунд.
Отправьте решение, чтобы увидеть результаты тестов.
