Данные переживают перезапуск

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 не очищает таблицу.

О данных в ответах

Используйте учебные данные. Не вставляйте пароли, токены, ключи доступа, паспортные и банковские данные, а также персональные данные других людей. Политика обработки данных.

РешениеPython · Python 3.12 (web: FastAPI, SQLAlchemy, pytest)
Как проверяется решение

Проверяются функции и их результаты. Собственный запуск выполняет ваш код без авторских тестов. Интерактивный запуск не влияет на оценку. Лимит сессии — 5 минут, процессорного времени — 10 секунд.

Отправьте решение, чтобы увидеть результаты тестов.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.