Продолжаем изучать Алхимию SQL, первая часть:
В этой части нужно модернизировать наше приложение по управлению книгами, студентами, авторами и "взял-сдал" в нашей электронной библиотеке.
На примере таблиц из предыдущего ДЗ:
1. Проведите доработку моделей:
добавьте к моделям связи и внешние ключи;
опишите каскадное поведение;
опишите способы подгрузки данных — используйте различные типы «жадной подгрузки»;
реализуйте связь MANY-TO-MANY для таблиц students — receiving_books — books с помощью AssociationProxy.
2. Добавьте роуты во flask-приложение:
получите количество оставшихся в библиотеке книг по автору (GET — входной параметр — ID автора);
получите список книг, которые студент не читал, при этом другие книги этого автора студент уже брал (GET — входной параметр — ID студента).Пример:
Я брал книгу Льва Толстого «Война и мир», роут должен вернуть другие произведения этого автора, которые есть в библиотеке.
получите среднее количество книг, которые студенты брали в этом месяце (GET);
получите самую популярную книгу среди студентов, у которых средний балл больше 4.0 (GET);
получите ТОП-10 самых читающих студентов в этом году (GET).
3. Создайте роут, который будет принимать csv-файл с данными по студентам (разделитель «;»). Используя csv.DictReader, обработайте файл и задействуйте Session.bulk_insert_mappings() для массовой вставки студентов.
4. По желанию. Создайте триггер события перед вставкой в таблицу students. Триггер должен проверять, что номер телефона имеет формат +7(9**)-***-**-**, где * — цифра от 0 до 9.
Что должны получить на выходе?!
Умение связывать таблицы с помощью ORM.
Понимание каскадного поведения.
Понимание подгрузки данных.
Работа со сложными запросами (group_by, order_by, subquery, func).
Работа с массовой вставкой.
Создание ORM Events.
Я так долго делал данное задание, что реализовывать "триггер события" уже поленился, так не терпелось сдать задание на проверку.
Данное задание я уже делал с использованием Postgresql. После выполнения хотел было перевести на Sqlite, но там появились проблемы совместимости. Почему-то не заработало autoincrement=True, в поле id. Выскочила какая-то ошибка и я уже не стал заморачиваться с поиском решения. А просто спросил у куратора о возможности принять задание на базе postgres.
Был создан новый проект, причем даже не на гитлаб или гитхаб, а на гитвёрс от Сбера. Я подумал - а почему бы не попробовать отечественный сервис гит?! А то санкции и прочая дичь... Докерхаб тому в пример.
Были использованы следующие зависимости:
Данное задание я выполнил как полноценный сайт, со страничками, но без особого дизана, из дизайна только подключенная библиотека CSS в HTML коде. Сайт выглядит так:
Дизайн проявляется в таблицах, примерно так:
Самое сложное в данной работе - понять как работает AssociationProxy. И не факт что я осознал как оно работает, потому как сто раз прочитал документацию и ни разу не понял взаимосвязи. Пришлось попросить помощи у студента этого курса, который осознал эту сущность...
Структура приложения такова:
Существует две директории: .venv (virtual environment) и app (само приложение). А так же несколько файлов: .gitignore - список расширений файлов которые не нужно загружать в git. example.csv - файл с именами, фамилиями и прочими данными студентов, которые нужно загружать в одном из заданий. readme.md - минимальное описание проекта. requirements.txt - список зависимостей, которые нужно установить для полноценной работы приложения.
__init__.py - файл в котором инициализируется Flask-приложение, прописывается подключение к базе данных postgres:
Подключается файл views.py, в котором будут прописаны все конечные точки, примерно выглядит так:
Подробней расскажу позже...
Файл run.py, который создает таблицы в базе данных и наполняет её какими-то минимальными данными, чтобы с ними можно было оперировать в дальнейшем:
Итак, начнем с моделей. Каждую модель я упаковал в отдельный файл, и все модели упакованы в директорию models, верней, правильно назвать python-пакет, потому как присутствует файл __init__.py и он не пустой:
В этом файле создается движок и и сессия для работы с базой данных.
Ну и по порядку, покажу все модели:
Самая сложная, для меня, модель - Student:
И вытекающая из модели Student модель ReceivingBook:
Ещё раз повторюсь, с association_proxy я так и не разобрался, вроде бы сделано а понимания в голове не осталось...
Следующий файл - класс, который очищает все таблицы от имеющихся данных, создаёт таблицы и наполняет их данными. Он вызывается в файле run.py:
Ну вот, все модели прописаны, можно создавать эндпойнты для операций с данными. Всё происходит в файле views.py, это самый большой файл во всём проекте, вначале идут операции, которые были у меня в первой части SQLAlchemy:
Далее идёт реализация энпойнтов, относящихся к заданию 21:
Ну вот все эндпойнты описаны осталось две директории, в одной лежат статик-файлы (css, javascrip, jpg и прочие), в моём же случае это один лишь файл style.css, который делает таблицы более симпатичными.
И последняя директория - templates, в которой находятся все html-файлы шаблонов куда передаётся контекст (данные, полученные и обработанные в формат json, из запроса к базе данных). Все файлы показывать не буду, они примерно идентичны этому:
Результат выполнения данного HTML-кода:
Ну вот, вроде бы и всё. С одной стороны банальная база данных с минимальным количеством таблиц, а с другой стороны я как-то очень долго въезжал в эту тему.
Всем добра, счастья, здоровья богатырского, а кто поставит лайк, тому исходный код в придачу!