diff --git a/01-introduction/README.md b/01-introduction/README.md new file mode 100644 index 0000000..cee8227 --- /dev/null +++ b/01-introduction/README.md @@ -0,0 +1,68 @@ +# Домашнее задание к лекции «Введение в БД. Типы БД» + +## Задание 1 (практика) + +Спроектировать схему — таблицы и связи между ними — для музыкального сайта. Требования: + +- на сайте должна быть возможность увидеть список музыкальных жанров; +- для каждого жанра можно получить список исполнителей, которые выступают в соответствующем жанре; +- для каждого исполнителя можно получить список его альбомов; +- для каждого альбома можно получить список треков, которые в него входят; +- у жанра есть название; +- у исполнителя есть имя (псевдоним) и жанр, в котором он исполняет; +- у альбома есть название, год выпуска и его исполнитель; +- у трека есть название, длительность и альбом, которому этот трек принадлежит. + +Результатом работы является изображение в формате PNG, содержащее схему БД. + +Для создания схем можно воспользоваться удобной платформой [app.diagrams.net](https://app.diagrams.net/) или любым другим графическим редактором. + +Краткая шпаргалка по созданию схем БД на платформе [app.diagrams.net](https://app.diagrams.net/) находится в личном кабинете в занятии «Введение в базы данных. Типы баз данных». + +## Задание 2 (подготовка к следующей лекции) + +Необходимо установить PostgreSQL на свой ПК. + +### Windows + +[Видеоинструкция](https://embed.new.video/uyjUq9B3qYo6BbbkzG71Ny). + +[Ссылка на PostgreSQL для Windows](https://www.enterprisedb.com/downloads/postgres-postgresql-downloads). + +### Linux (на примере Ubuntu 20.04) + +[Видеоинструкция](https://embed.new.video/cRQW4Z2YnxZUxzKRLWwnPF). + +Команды для установки: + +```bash +# PostgreSQL +sudo apt update && sudo apt install postgresql-12 + +# pgAdmin4 +wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - +echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |sudo tee /etc/apt/sources.list.d/pgdg.list +sudo apt update && sudo apt install pgadmin4 +``` + +### Mac OS X + +[Видеоинструкция](https://clck.ru/32zuuG) + +Команды для установки: + +```bash +brew install postgresql + +postgres -V + +pg_ctl -D /usr/local/var/postgres start + +createuser -P -s postgres +``` + +## Задание 3 (подготовка к следующей лекции) + +На следующей лекции мы будем использовать программу DBeaver Community для работы с СУБД. Это бесплатная программа, вы можете заранее скачать её [по ссылке](https://dbeaver.io/download/) и установить на свой компьютер. + +Обратите внимание, что это задание является рекомендацией, для полноценного участия в лекции DBeaver вам не потребуется, вы можете установить эту программу позже или вообще использовать что-то другое. diff --git a/02-creation/README.md b/02-creation/README.md new file mode 100644 index 0000000..1dba0bf --- /dev/null +++ b/02-creation/README.md @@ -0,0 +1,38 @@ +# Домашнее задание к лекции «Работа с SQL. Создание БД» + +## Задание + +### Обязательная часть + +Будем развивать схему для музыкального сервиса. + +Ранее существовало ограничение, что каждый исполнитель поёт строго в одном жанре, пора его убрать. Исполнители могут петь в разных жанрах, как и одному жанру могут принадлежать несколько исполнителей. + +Аналогичное ограничение было и с альбомами у исполнителей — альбом мог выпустить только один исполнитель. Теперь альбом могут выпустить несколько исполнителей вместе. Как и исполнитель может принимать участие во множестве альбомов. + +С треками ничего не меняем, всё так же трек принадлежит строго одному альбому. + +Но появилась новая сущность — сборник. Сборник имеет название и год выпуска. В него входят различные треки из разных альбомов. + +_Обратите внимание_: один и тот же трек может присутствовать в разных сборниках. + +Задание состоит из двух частей + +1. Спроектировать и нарисовать схему, как в [первой домашней работе](../01-introduction). Прислать изображение со схемой. +2. Написать SQL-запросы, создающие спроектированную БД. Прислать ссылку на файл, содержащий SQL-запросы. + +_Примечание:_ можно прислать сначала схему, получить подтверждение, что схема верная, и после этого браться за написание запросов. + +--- + +### Дополнительное (необязательное) задание + +Спроектировать отношение или схему из нескольких отношений «Сотрудник». У каждого сотрудника есть следующие параметры: + +1. Имя. +2. Отдел. +3. Начальник (ссылка на начальника). + +_Примечание:_ начальник — тоже сотрудник. Отдел можно хранить строкой, можно идентификатором — не принципиально. + +Необходимо написать SQL-запрос, создающий таблицу «Сотрудник», и прислать ссылку на файл с этим запросом. diff --git a/04-dml/README.md b/04-dml/README.md new file mode 100644 index 0000000..e532571 --- /dev/null +++ b/04-dml/README.md @@ -0,0 +1,161 @@ +# Домашнее задание к лекции «Продвинутая выборка данных» + +## Задание 1 + +Продолжаем работать со своей базой данных. В этом задании заполните базу данных из домашнего задания к занятию "Работа с SQL. Создание БД". В ней должно быть: + +- не менее 4 исполнителей, +- не менее 3 жанров, +- не менее 3 альбомов, +- не менее 6 треков, +- не менее 4 сборников. + +Внимание: должны быть заполнены все поля каждой таблицы, в том числе таблицы связей исполнителей с жанрами, исполнителей с альбомами, сборников с треками. + +## Ответ 1 + +CREATE TABLE Исполнители ( + Идентификатор INT PRIMARY KEY, + Имя VARCHAR(255) +); + +CREATE TABLE Жанры ( + Идентификатор INT PRIMARY KEY, + Название VARCHAR(255) +); + +CREATE TABLE Альбомы ( + Идентификатор INT PRIMARY KEY, + Название VARCHAR(255), + Год_выпуска INT +); + +CREATE TABLE Треки ( + Идентификатор INT PRIMARY KEY, + Название VARCHAR(255), + Идентификатор_альбома INT, + FOREIGN KEY (Идентификатор_альбома) REFERENCES Альбомы(Идентификатор) +); + +CREATE TABLE Сборники ( + Идентификатор INT PRIMARY KEY, + Название VARCHAR(255), + Год_выпуска INT +); + +CREATE TABLE Исполнители_Жанры ( + Идентификатор INT PRIMARY KEY, + Идентификатор_исполнителя INT, + Идентификатор_жанра INT, + FOREIGN KEY (Идентификатор_исполнителя) REFERENCES Исполнители(Идентификатор), + FOREIGN KEY (Идентификатор_жанра) REFERENCES Жанры(Идентификатор) +); + +CREATE TABLE Исполнители_Альбомы ( + Идентификатор INT PRIMARY KEY, + Идентификатор_исполнителя INT, + Идентификатор_альбома INT, + FOREIGN KEY (Идентификатор_исполнителя) REFERENCES Исполнители(Идентификатор), + FOREIGN KEY (Идентификатор_альбома) REFERENCES Альбомы(Идентификатор) +); + +CREATE TABLE Альбомы_Треки ( + Идентификатор INT PRIMARY KEY, + Идентификатор_альбома INT, + Идентификатор_трека INT, + FOREIGN KEY (Идентификатор_альбома) REFERENCES Альбомы(Идентификатор), + FOREIGN KEY (Идентификатор_трека) REFERENCES Треки(Идентификатор) +); + +CREATE TABLE Сборники_Треки ( + Идентификатор INT PRIMARY KEY, + Идентификатор_сборника INT, + Идентификатор_трека INT, + FOREIGN KEY (Идентификатор_сборника) REFERENCES Сборники(Идентификатор), + FOREIGN KEY (Идентификатор_трека) REFERENCES Треки(Идентификатор) +); + +## Задание 2 + +Написать SELECT-запросы, которые выведут информацию согласно инструкциям ниже. + +Внимание: результаты запросов не должны быть пустыми, учтите это при заполнении таблиц. + +1. Название и продолжительность самого длительного трека. +2. Название треков, продолжительность которых не менее 3,5 минут. +3. Названия сборников, вышедших в период с 2018 по 2020 год включительно. +4. Исполнители, чьё имя состоит из одного слова. +5. Название треков, которые содержат слово «мой» или «my». + + +## Ответ 2 + +SELECT Название, Продолжительность +FROM Треки +WHERE Продолжительность = (SELECT MAX(Продолжительность) FROM Треки); + +SELECT Название +FROM Треки +WHERE Продолжительность >= 3.5; + +SELECT Название +FROM Сборники +WHERE Год_выпуска BETWEEN 2018 AND 2020; + +SELECT Имя +FROM Исполнители +WHERE Имя NOT LIKE '% %'; + +SELECT Название +FROM Треки +WHERE Название LIKE '%мой%' OR Название LIKE '%my%'; + + +## Задание 3 + +Написать SELECT-запросы, которые выведут информацию согласно инструкциям ниже. + +Внимание: результаты запросов не должны быть пустыми, при необходимости добавьте данные в таблицы. + +1. Количество исполнителей в каждом жанре. +2. Количество треков, вошедших в альбомы 2019–2020 годов. +3. Средняя продолжительность треков по каждому альбому. +4. Все исполнители, которые не выпустили альбомы в 2020 году. +5. Названия сборников, в которых присутствует конкретный исполнитель (выберите его сами). + +## Ответ 3 + +SELECT Жанры.Название AS Жанр, COUNT(*) AS Количество_исполнителей +FROM Жанры +LEFT JOIN Исполнители ON Жанры.Идентификатор = Исполнители.Идентификатор_жанра +GROUP BY Жанры.Название; + +SELECT COUNT(*) AS Количество_треков +FROM Треки +JOIN Альбомы ON Треки.Идентификатор_альбома = Альбомы.Идентификатор +WHERE Альбомы.Год_выпуска BETWEEN 2019 AND 2020; + +SELECT Альбомы.Название AS Название_альбома, AVG(Треки.Продолжительность) AS Средняя_продолжительность +FROM Треки +JOIN Альбомы ON Треки.Идентификатор_альбома = Альбомы.Идентификатор +GROUP BY Альбомы.Название; + +SELECT Исполнители.Имя +FROM Исполнители +LEFT JOIN Альбомы ON Исполнители.Идентификатор = Альбомы.Идентификатор_исполнителя +WHERE YEAR(Альбомы.Год_выпуска) <> 2020 OR Альбомы.Год_выпуска IS NULL; + +SELECT Сборники.Название +FROM Сборники +JOIN Сборники_Треки ON Сборники.Идентификатор = Сборники_Треки.Идентификатор_сборника +JOIN Треки ON Сборники_Треки.Идентификатор_трека = Треки.Идентификатор +WHERE Треки.Идентификатор_исполнителя = 1; + + +--- + +Результатом работы будет три файла в формате `.sql`: + +- с INSERT-запросами (задание 1), +- с SELECT-запросами (задание 2,3,4), +- с CREATE-запросами (из предыдущей домашней работы). diff --git a/05-psycopg/README.md b/05-psycopg/README.md new file mode 100644 index 0000000..266002a --- /dev/null +++ b/05-psycopg/README.md @@ -0,0 +1,71 @@ +# Домашнее задание к лекции «Работа с PostgreSQL из Python» + +Создайте программу для управления клиентами на Python. + +Требуется хранить персональную информацию о клиентах: + +- имя, +- фамилия, +- email, +- телефон. + +Сложность в том, что телефон у клиента может быть не один, а два, три и даже больше. А может и вообще не быть телефона, например, он не захотел его оставлять. + +Вам необходимо разработать структуру БД для хранения информации и несколько функций на Python для управления данными. + +1. Функция, создающая структуру БД (таблицы). +1. Функция, позволяющая добавить нового клиента. +1. Функция, позволяющая добавить телефон для существующего клиента. +1. Функция, позволяющая изменить данные о клиенте. +1. Функция, позволяющая удалить телефон для существующего клиента. +1. Функция, позволяющая удалить существующего клиента. +1. Функция, позволяющая найти клиента по его данным: имени, фамилии, email или телефону. + +Функции выше являются обязательными, но это не значит, что должны быть только они. При необходимости можете создавать дополнительные функции и классы. + +Также предоставьте код, демонстрирующий работу всех написанных функций. + +Результатом работы будет `.py` файл. + +--- + +## Подсказка + +> Не читайте этот раздел сразу, попытайтесь сначала решить задачу самостоятельно :) + +
+ +Каркас кода + +```py +import psycopg2 + +def create_db(conn): + pass + +def add_client(conn, first_name, last_name, email, phones=None): + pass + +def add_phone(conn, client_id, phone): + pass + +def change_client(conn, client_id, first_name=None, last_name=None, email=None, phones=None): + pass + +def delete_phone(conn, client_id, phone): + pass + +def delete_client(conn, client_id): + pass + +def find_client(conn, first_name=None, last_name=None, email=None, phone=None): + pass + + +with psycopg2.connect(database="clients_db", user="postgres", password="postgres") as conn: + pass # вызывайте функции здесь + +conn.close() +``` + +
diff --git a/06-orm/README.md b/06-orm/README.md new file mode 100644 index 0000000..d4c55c5 --- /dev/null +++ b/06-orm/README.md @@ -0,0 +1,86 @@ +# Домашнее задание к лекции «Python и БД. ORM» + +## Задание 1 + +Составить модели классов SQLAlchemy по схеме: + +![](readme/book_publishers_scheme.png) + +Легенда: система хранит информацию об издателях (авторах), их книгах и фактах продажи. Книги могут продаваться в разных магазинах, поэтому требуется учитывать не только что за книга была продана, но и в каком магазине это было сделано, а также когда. + +Интуитивно необходимо выбрать подходящие типы и связи полей. + +## Задание 2 + +Используя SQLAlchemy, составить запрос выборки магазинов, продающих целевого издателя. + +Напишите Python-скрипт, который: + +- подключается к БД любого типа на ваш выбор, например, к PostgreSQL; +- импортирует необходимые модели данных; +- принимает имя или идентификатор издателя (publisher), например, через `input()`. Выводит построчно факты покупки книг этого издателя: + +``` +название книги | название магазина, в котором была куплена эта книга | стоимость покупки | дата покупки +``` + +Пример (было введено имя автора — `Пушкин`): + +``` +Капитанская дочка | Буквоед | 600 | 09-11-2022 +Руслан и Людмила | Буквоед | 500 | 08-11-2022 +Капитанская дочка | Лабиринт | 580 | 05-11-2022 +Евгений Онегин | Книжный дом | 490 | 02-11-2022 +Капитанская дочка | Буквоед | 600 | 26-10-2022 +``` + +## Задание 3 (необязательное) + +Заполните БД тестовыми данными. + +Тестовые данные берутся из папки `fixtures`. Пример содержания в JSON-файле. + +Возможная реализация: прочитать JSON-файл, создать соотведствующие экземляры моделей и сохранить в БД. + +
+ +Пример реализации, но сначала попытайтесь самостоятельно ;) + +```python +import json + +import sqlalchemy +from sqlalchemy.orm import sessionmaker + +from models import create_tables, Publisher, Shop, Book, Stock, Sale + + +DSN = '...' +engine = sqlalchemy.create_engine(DSN) +create_tables(engine) + +Session = sessionmaker(bind=engine) +session = Session() + +with open('fixtures/tests_data.json', 'r') as fd: + data = json.load(fd) + +for record in data: + model = { + 'publisher': Publisher, + 'shop': Shop, + 'book': Book, + 'stock': Stock, + 'sale': Sale, + }[record.get('model')] + session.add(model(id=record.get('pk'), **record.get('fields'))) +session.commit() +``` + +
+ +## Общие советы + +- Параметры подключения к БД следует выносить в отдельные переменные: логин, пароль, название БД и пр. +- Загружать значения лучше из окружения ОС, например, через `os.getenv()`. +- Заполнять данными можно вручную или выполнить необязательное задание 3. diff --git a/06-orm/fixtures/tests_data.json b/06-orm/fixtures/tests_data.json new file mode 100644 index 0000000..a68fdb8 --- /dev/null +++ b/06-orm/fixtures/tests_data.json @@ -0,0 +1,31 @@ +[ + {"model": "publisher", "pk": 1, "fields": {"name": "O\u2019Reilly"}}, + {"model": "publisher", "pk": 2, "fields": {"name": "Pearson"}}, + {"model": "publisher", "pk": 3, "fields": {"name": "Microsoft Press"}}, + {"model": "publisher", "pk": 4, "fields": {"name": "No starch press"}}, + {"model": "book", "pk": 1, "fields": {"title": "Programming Python, 4th Edition", "id_publisher": 1}}, + {"model": "book", "pk": 2, "fields": {"title": "Learning Python, 4th Edition", "id_publisher": 1}}, + {"model": "book", "pk": 3, "fields": {"title": "Natural Language Processing with Python", "id_publisher": 1}}, + {"model": "book", "pk": 4, "fields": {"title": "Hacking: The Art of Exploitation", "id_publisher": 4}}, + {"model": "book", "pk": 5, "fields": {"title": "Modern Operating Systems", "id_publisher": 2}}, + {"model": "book", "pk": 6, "fields": {"title": "Code Complete: Second Edition", "id_publisher": 3}}, + {"model": "shop", "pk": 1, "fields": {"name": "Labirint"}}, + {"model": "shop", "pk": 2, "fields": {"name": "OZON"}}, + {"model": "shop", "pk": 3, "fields": {"name": "Amazon"}}, + {"model": "stock", "pk": 1, "fields": {"id_shop": 1, "id_book": 1, "count": 34}}, + {"model": "stock", "pk": 2, "fields": {"id_shop": 1, "id_book": 2, "count": 30}}, + {"model": "stock", "pk": 3, "fields": {"id_shop": 1, "id_book": 3, "count": 0}}, + {"model": "stock", "pk": 4, "fields": {"id_shop": 2, "id_book": 5, "count": 40}}, + {"model": "stock", "pk": 5, "fields": {"id_shop": 2, "id_book": 6, "count": 50}}, + {"model": "stock", "pk": 6, "fields": {"id_shop": 3, "id_book": 4, "count": 10}}, + {"model": "stock", "pk": 7, "fields": {"id_shop": 3, "id_book": 6, "count": 10}}, + {"model": "stock", "pk": 8, "fields": {"id_shop": 2, "id_book": 1, "count": 10}}, + {"model": "stock", "pk": 9, "fields": {"id_shop": 3, "id_book": 1, "count": 10}}, + {"model": "sale", "pk": 1, "fields": {"price": "50.05", "date_sale": "2018-10-25T09:45:24.552Z", "count": 16, "id_stock": 1}}, + {"model": "sale", "pk": 2, "fields": {"price": "50.05", "date_sale": "2018-10-25T09:51:04.113Z", "count": 10, "id_stock": 3}}, + {"model": "sale", "pk": 3, "fields": {"price": "10.50", "date_sale": "2018-10-25T09:52:22.194Z", "count": 9, "id_stock": 6}}, + {"model": "sale", "pk": 4, "fields": {"price": "16.00", "date_sale": "2018-10-25T10:59:56.230Z", "count": 5, "id_stock": 5}}, + {"model": "sale", "pk": 5, "fields": {"price": "16.00", "date_sale": "2018-10-25T10:59:56.230Z", "count": 5, "id_stock": 9}}, + {"model": "sale", "pk": 6, "fields": {"price": "16.00", "date_sale": "2018-10-25T10:59:56.230Z", "count": 1, "id_stock": 4}} +] + diff --git a/orm/readme/book_publishers_scheme.png b/06-orm/readme/book_publishers_scheme.png similarity index 100% rename from orm/readme/book_publishers_scheme.png rename to 06-orm/readme/book_publishers_scheme.png diff --git a/README.md b/README.md index 879b2fd..5af9df7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Домашние задания на курсе «Python. Базы данных» -1. [Введение в БД. Типы БД](introduction) -2. [Работа с PostgreSQL. Создание БД](creation) -3. [Проектирование БД. Связи. 3НФ](design) -4. [Select-запросы, выборки из одной таблицы](dml) -5. [Группировки, выборки из нескольких таблиц](dml-advanced) +1. [Введение в базы данных. Типы баз данных](./01-introduction) +1. [Работа с SQL. Создание БД](./02-creation) +1. Select-запросы, выборки из одной таблицы (чтобы прокачать свои навыки работы с запросами в БД, выполните задания с тренажёрами в своём личном кабинете) +1. [Продвинутая выборка данных](./04-dml) +1. [Работа с PostgreSQL из Python](./05-psycopg) +1. [Python и БД. ORM](./06-orm) diff --git a/creation/README.md b/creation/README.md deleted file mode 100644 index d6408c6..0000000 --- a/creation/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Домашнее задание к лекции «Работа с PostgreSQL. Создание БД» - -Написать SQL-запросы для создания таблиц из схемы, реализованной в [предыдущем домашнем задании](../introduction). - -Результатом работы является файл, содержащий SQL-запросы. diff --git a/design/README.md b/design/README.md deleted file mode 100644 index d6a3a4a..0000000 --- a/design/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Домашнее задание к лекции «Проектирование БД. Связи. 3НФ» - -## Задание - -### Обязательная часть - -Будем развивать схему для музыкального сервиса. - -Ранее было ограничение, что каждый исполнитель поет строго в одном жанре - пора убрать это ограничение. Исполнители могут петь в разных жанрах, как и одному жанру могут принадлежать несколько исполнителей. - -Аналогичное ограничение было и с альбомами у исполнителей (альбом мог выпустить только один исполнитель). Теперь альбом могут выпустить несколько исполнителей вместе. Как и исполнитель может принимать участие во множестве альбомов. - -С треками ничего не меняем, все так же трек принадлежит строго одному альбому. - -Но появилась новая сущность - сборник. Сборник имеет название и год выпуска. В него входят различные треки из разных альбомов. - -_Обратите внимание_: один и тот же трек может присутствовать в разных сборниках. - -Задание состоит из двух частей: - -1. Спроектировать и нарисовать схему (как в [первой домашней работе](../introduction)). Прислать изображение со схемой. -2. Написать SQL-запросы, создающие спроектированную БД (как во [второй домашней работе](../creation)). Прислать ссылку на файл, содержащий SQL-запросы. - -_Примечание:_ можно прислать сначала схему, получить подтверждение, что схема верная и после этого браться за написание запросов. - -### Дополнительное (необязательное) задание - -Спроектировать отношение (или схему из нескольких отношений) "Сотрудник". У каждого сотрудника есть следующие параметры: - -1. Имя -2. Отдел -3. Начальник (ссылка на начальника) - -_Примечание:_ начальник - тоже сотрудник. Отдел можно хранить строкой, можно идентификатором (не принципиально). - -Необходимо написать SQL-запрос, создающий таблицу "Сотрудник", и прислать ссылку на файл с этим запросом. diff --git a/dml-advanced/README.md b/dml-advanced/README.md deleted file mode 100644 index 01b91e2..0000000 --- a/dml-advanced/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Домашнее задание к лекции «Группировки, выборки из нескольких таблиц» - -Написать SELECT-запросы, которые выведут информацию согласно инструкциям ниже. -Внимание! Результаты запросов не должны быть пустыми (при необходимости добавьте данные в таблицы). - -1. количество исполнителей в каждом жанре; -2. количество треков, вошедших в альбомы 2019-2020 годов; -3. средняя продолжительность треков по каждому альбому; -4. все исполнители, которые не выпустили альбомы в 2020 году; -5. названия сборников, в которых присутствует конкретный исполнитель (выберите сами); -6. название альбомов, в которых присутствуют исполнители более 1 жанра; -7. наименование треков, которые не входят в сборники; -8. исполнителя(-ей), написавшего самый короткий по продолжительности трек (теоретически таких треков может быть несколько); -9. название альбомов, содержащих наименьшее количество треков. - -Результатом работы будет 3 файла (с INSERT, SELECT запросами и CREATE запросами из предыдущего задания) в формате .sql (или .py/.ipynb, если вы будете писать запросы с использованием SQLAlchemy). -В случае если INSERT- и CREATE-запросы остались без изменений, приложите файлы c ними из предыдущих домашних заданий. diff --git a/dml/README.md b/dml/README.md deleted file mode 100644 index 58dfe6f..0000000 --- a/dml/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Домашнее задание к лекции «Select-запросы, выборки из одной таблицы» - -## Задание 1 - -Заполните базу данных из предыдущего домашнего задания. В ней должно быть: - -* не менее 8 исполнителей; -* не менее 5 жанров; -* не менее 8 альбомов; -* не менее 15 треков; -* не менее 8 сборников. -Внимание! Должны быть заполнены все поля каждой таблицы, в т.ч. таблицы связей (исполнителей с жанрами, исполнителей с альбомами, сборников с треками). - -## Задание 2 - -Написать SELECT-запросы, которые выведут информацию согласно инструкциям ниже. -Внимание! Результаты запросов не должны быть пустыми (учтите при заполнении таблиц). - -1. название и год выхода альбомов, вышедших в 2018 году; -2. название и продолжительность самого длительного трека; -3. название треков, продолжительность которых не менее 3,5 минуты; -4. названия сборников, вышедших в период с 2018 по 2020 год включительно; -5. исполнители, чье имя состоит из 1 слова; -6. название треков, которые содержат слово "мой"/"my". - -Результатом работы будет 3 файла (с INSERT, SELECT запросами и CREATE запросами из предыдущего задания) в формате .sql (или .py/.ipynb, если вы будете писать запросы с использованием SQLAlchemy). diff --git a/introduction/README.md b/introduction/README.md deleted file mode 100644 index 5fd21a9..0000000 --- a/introduction/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Домашнее задание к лекции «Введение в БД. Типы БД» - -## Задание 1 (практика) - -### Обязательная часть - -Спроектировать схему (таблицы и связи между ними) для музыкального сайта. Требования: - -- На сайте должна быть возможность увидеть список исполнителей. -- Для каждого исполнителя можно получить список его альбомов. -- Для каждого альбома можно получить список треков, которые в него входят. -- У исполнителя есть имя (псевдоним). -- У альбома есть название и год выпуска. -- У трека есть название и длительность. -- Трек входит только в один альбом, как и альбом принадлежит только одному исполнителю (это искусственное ограничение, чтобы схема была проще, далее по курсу мы избавимся от этого ограничения). - -Результатом работы является изображение в формате PNG, содержащее схему БД. - -Для создания схем можно воспользоваться удобной платформой [draw.io](https://draw.io) или любым другм графическим редактором. - -[Краткая шпаргалка](https://docs.google.com/document/d/1KUagjHQQHIQYS2-qI0lgiV2wNxKdi00Q_Xw0nK7t3PA/edit?usp=sharing) по созданию схем БД на платформе [draw.io](https://draw.io). - -### Дополнительное (необязательное) задание - -Добавить к схеме жанры. Требования: - -- На сайте должна быть возможность увидеть список жанров. -- Для каждого жанра можно получить список исполнителей, которые поют в данном жанре. -- У жанра есть название. -- Исполнитель поет только в одном жанре (это искусственное ограничение, чтобы схема была проще, далее по курсу мы избавимся от этого ограничения). - -## Задание 2 (подготовка к следующей лекции) - -Необходимо установить PostgreSQL на свой ПК. - -### Windows - -[Видео-инструкция](https://embed.new.video/uyjUq9B3qYo6BbbkzG71Ny) - -[Ссылка на PostgreSQL для Windows](https://www.enterprisedb.com/downloads/postgres-postgresql-downloads) - -### Linux (на примере Ubuntu 20.04) - -[Видео-инструкция](https://embed.new.video/cRQW4Z2YnxZUxzKRLWwnPF) - -Команды для установки: - -```bash -# PostgreSQL -sudo apt update && sudo apt install postgresql-12 - -# pgAdmin4 -wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - -echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |sudo tee /etc/apt/sources.list.d/pgdg.list -sudo apt update && sudo apt install pgadmin4 -``` - -### Mac OS X - -[Видео-инструкция](https://kinescope.io/200639959) - -Команды для установки: - -```bash -brew install postgres - -postgres -V - -pg_ctl -D /usr/local/var/postgres start - -createuser -P -s postgres -``` - -## Задание 3 (подготовка к следующей лекции) - -На следующей лекции мы будем использовать программу DBeaver Community для работы с СУБД. Это бесплатная программа, вы можете заранее скачать ее [по ссылке](https://dbeaver.io/download/) и установить на свой компьютер. -Обратите внимание, что данное задание является рекомендацией, для полноценного участия в лекции DBeaver вам не потребуется, вы можете установить эту программу позже (или даже вообще использовать что-то другое). - diff --git a/orm/README.md b/orm/README.md deleted file mode 100644 index 635c3a7..0000000 --- a/orm/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Домашнее задание к лекции «Python и БД. ORM» - -## Задание 1 - -Составить модели классов SQLAlchemy по схеме: -![](readme/book_publishers_scheme.png) -Интуитивно необходимо выбрать подходящие типы и связи полей. - -## Задание 2 - -Используя SQLAlchemy, составить запрос выборки магазинов, продающих целевого издателя. - -Напишите Python скрипт, который: - -- Подключается к БД любого типа на ваш выбор. -- Импортирует необходимые модели данных. -- Выполняет запрос для целевого издателя, имя или идентификатор которого принимается через input. - - -## Задание 3.1 (необязательное) - -- Настроить миграции через alembic. Миграция инициализации таблиц создается автоматически на основе модели данных. - -## Задание 3.2 (необязательное) - -- Заполнение тестовых данных через миграцию или внешний скрипт. -- Тестовые данные берутся из папки `fixtures`. Пример содержания в JSON файле. - -Возможно несколько вариантов реализации: - -1. Парсится json, создаются соотведствующие экземляры моделей и сохраняются в БД. -2. Создаются новые фикстуры взамен JSON на основе [SQLAlchemy-Fixtures](https://sqlalchemy-fixtures.readthedocs.io/en/latest/) или [FactoryBoy](https://github.com/FactoryBoy/factory_boy) - -## Общие советы: - -- Параметры подключения к БД выносятся в отдельные переменные. -- Загружать значения из окружения ОС, например через `os.getenv`. -- Для самотестирования задания 2 рекомендуется выполнить задание 3.1, чтобы не создавать БД вручную или применить [create_all](https://docs.sqlalchemy.org/en/13/core/metadata.html#creating-and-dropping-database-tables). -- Заполнять можно вручную или выполнить 3.2. diff --git a/orm/fixtures/tests_data.json b/orm/fixtures/tests_data.json deleted file mode 100644 index 0d33a52..0000000 --- a/orm/fixtures/tests_data.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - {"model": "publisher", "pk": 1, "fields": {"name": "O\u2019Reilly"}}, - {"model": "publisher", "pk": 2, "fields": {"name": "Pearson"}}, - {"model": "publisher", "pk": 3, "fields": {"name": "Microsoft Press"}}, - {"model": "publisher", "pk": 4, "fields": {"name": "No starch press"}}, - {"model": "book", "pk": 1, "fields": {"title": "Programming Python, 4th Edition", "publisher": 1}}, - {"model": "book", "pk": 2, "fields": {"title": "Learning Python, 4th Edition", "publisher": 1}}, - {"model": "book", "pk": 3, "fields": {"title": "Natural Language Processing with Python", "publisher": 1}}, - {"model": "book", "pk": 4, "fields": {"title": "Hacking: The Art of Exploitation", "publisher": 4}}, - {"model": "book", "pk": 5, "fields": {"title": "Modern Operating Systems", "publisher": 2}}, - {"model": "book", "pk": 6, "fields": {"title": "Code Complete: Second Edition", "publisher": 3}}, - {"model": "shop", "pk": 1, "fields": {"name": "Labirint"}}, - {"model": "shop", "pk": 2, "fields": {"name": "OZON"}}, - {"model": "shop", "pk": 3, "fields": {"name": "Amazon"}}, - {"model": "stock", "pk": 1, "fields": {"shop": 1, "book": 1, "count": 34}}, - {"model": "stock", "pk": 2, "fields": {"shop": 1, "book": 2, "count": 30}}, - {"model": "stock", "pk": 3, "fields": {"shop": 1, "book": 3, "count": 0}}, - {"model": "stock", "pk": 4, "fields": {"shop": 2, "book": 5, "count": 40}}, - {"model": "stock", "pk": 5, "fields": {"shop": 2, "book": 6, "count": 50}}, - {"model": "stock", "pk": 6, "fields": {"shop": 3, "book": 4, "count": 10}}, - {"model": "stock", "pk": 7, "fields": {"shop": 3, "book": 6, "count": 10}}, - {"model": "stock", "pk": 8, "fields": {"shop": 2, "book": 1, "count": 10}}, - {"model": "stock", "pk": 9, "fields": {"shop": 3, "book": 1, "count": 10}}, - {"model": "sale", "pk": 1, "fields": {"price": "50.05", "date_sale": "2018-10-25T09:45:24.552Z", "count": 16, "stock": 1}}, - {"model": "sale", "pk": 2, "fields": {"price": "50.05", "date_sale": "2018-10-25T09:51:04.113Z", "count": 10, "stock": 3}}, - {"model": "sale", "pk": 3, "fields": {"price": "10.50", "date_sale": "2018-10-25T09:52:22.194Z", "count": 9, "stock": 6}}, - {"model": "sale", "pk": 4, "fields": {"price": "16.00", "date_sale": "2018-10-25T10:59:56.230Z", "count": 5, "stock": 5}}, - {"model": "sale", "pk": 5, "fields": {"price": "16.00", "date_sale": "2018-10-25T10:59:56.230Z", "count": 5, "stock": 9}}, - {"model": "sale", "pk": 6, "fields": {"price": "16.00", "date_sale": "2018-10-25T10:59:56.230Z", "count": 1, "stock": 4}}, -]