
Лабораторная работа №1. БД-1
.pdfМИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ федеральное государственное автономное образовательное учреждение высшего образования
«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»
ИНСТИТУТ НЕПРЕРЫВНОГО И ДИСТАНЦИОННОГО ОБРАЗОВАНИЯ
КАФЕДРА ПРИКЛАДНОЙ ИНФОРМАТИКИ
ОЦЕНКА |
|
|
ПРЕПОДАВАТЕЛЬ |
|
|
канд. техн. наук, доцент |
подпись, дата |
Е. Л. Турнецкая |
должность, уч. степень, звание |
инициалы, фамилия |
ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ
Лабораторная работа №1. Связь СУБД PostgreSQL и Python. Визуализация данных в Python
по дисциплине: Базы данных
РАБОТУ ВЫПОЛНИЛ |
|
|
|
|
|
СТУДЕНТ гр. № |
Z1411 |
|
|
Я. Н. Тюттерин |
|
|
номер группы |
|
подпись, дата |
|
инициалы, фамилия |
Студенческий билет № |
2022 / 4886 |
|
|
|
Санкт-Петербург 2024
Лабораторная работа № 1 Связь СУБД PostgreSQL и Python. Визуализация данных в Python
Цель работы: произвести связь базы данных в PostgreSQL и Python, извлечь данные из таблиц базы данных и выполнить анализ данных в БД с помощью визуализации в Python.
Вначале был выполнен запрос к БД для создания схемы театра из прошлого семестра.
CREATE TABLE IF NOT EXISTS genres (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name varchar(15) not null unique
);
CREATE TABLE IF NOT EXISTS categories (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name varchar(15) not null unique
);
CREATE TABLE IF NOT EXISTS positions (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name varchar(15) not null UNIQUE
);
CREATE TABLE IF NOT EXISTS achievements (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name varchar(30) not null UNIQUE
);
CREATE TABLE IF NOT EXISTS workers (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, first_name varchar(30) not null,
last_name varchar(30) not null, patronymic varchar(30), gender char(1) not null,
salary DECIMAL(10,2) not null, date_of_birth date not null, voice integer,
height integer,
CONSTRAINT CHECK_GENDER CHECK (gender in('M','F','T'))
);
CREATE TABLE IF NOT EXISTS theaters (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, title varchar(30) not null,
director_id integer not null,
FOREIGN KEY (director_id) REFERENCES workers (id)
);
CREATE TABLE IF NOT EXISTS shows (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, title varchar(20) not null,
date timestamp not null, duration integer not null, theatre_id integer not null,
FOREIGN KEY (theatre_id) REFERENCES theaters (id)
);
CREATE TABLE IF NOT EXISTS roles (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name varchar(30) not null UNIQUE
);
CREATE TABLE IF NOT EXISTS subscriptions (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, price DECIMAL(10,2) not null
);
CREATE TABLE IF NOT EXISTS tickets (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, show_id integer not null,
available bool default true not null, subscription_id integer,
FOREIGN KEY (subscription_id) REFERENCES subscriptions (id), FOREIGN KEY (show_id) REFERENCES shows (id)
);
CREATE TABLE IF NOT EXISTS genre_show ( show_id integer not null,
genre_id integer not null,
CONSTRAINT PK_GENRE_SHOW PRIMARY KEY (show_id, genre_id), FOREIGN KEY (show_id) REFERENCES shows (id),
FOREIGN KEY (genre_id) REFERENCES genres (id)
);
CREATE TABLE IF NOT EXISTS achievement_worker ( achievement_id integer not null,
worker_id integer not null,
CONSTRAINT PK_WORKER_ACHIVEMENT PRIMARY key (achievement_id, worker_id), FOREIGN KEY (achievement_id) REFERENCES achievements (id),
FOREIGN KEY (worker_id) REFERENCES workers (id)
);
CREATE TABLE IF NOT EXISTS position_worker ( position_id integer not null,
worker_id integer not null, theater_id integer not null,
PRIMARY KEY (position_id, worker_id, theater_id), FOREIGN KEY (position_id) REFERENCES positions (id), FOREIGN KEY (worker_id) REFERENCES workers (id), FOREIGN KEY (theater_id) REFERENCES theaters (id)
);
CREATE TABLE IF NOT EXISTS category_show ( category_id integer not null,
show_id integer not null,
CONSTRAINT PK_CATEGORY_GENRE_SHOW PRIMARY KEY (category_id, show_id), FOREIGN KEY (category_id) REFERENCES categories (id),
FOREIGN KEY (show_id) REFERENCES shows (id)
);
CREATE TABLE IF NOT EXISTS role_show_worker ( show_id integer not null,
role_id integer not null, worker_id integer not null,
CONSTRAINT PK_ROLE_SHOW_WORKER PRIMARY KEY (show_id, worker_id, role_id), FOREIGN KEY (show_id) REFERENCES shows (id),
FOREIGN KEY (role_id) REFERENCES roles (id), FOREIGN KEY (worker_id) REFERENCES workers (id)
);
Результат выполнения представлен на рисунке 1. Для визуализации используется клиент DBEaver.

Рисунок 1 - Набор таблиц
Также необходимо произвести вставку записей в таблицы, на основе которых будет строиться диаграмма.
INSERT into positions (name) VALUES ('Режиссер'),
('Продюсер'), ('Актер'), ('Ведущий'), ('Уборщик'), ('Кассир');
INSERT INTO workers(first_name, last_name, patronymic, gender, salary, date_of_birth)
VALUES ('Kotov', 'Maksim', 'Igorevich', 'M', 100000, '1980-12-12'), ('Makarova', 'Anastasia', 'Maksimovna', 'F', 80000, '1989-08-10'), ('Zlatov', 'Igor', 'Vadimovich', 'M', 70000, '1980-10-11'), ('Mikhailov', 'Oleg', 'Aleksandrovich', 'M', 65000, '1995-09-14'),

('Kotova', 'Violetta', 'Vitalievna', 'F', 150000, '1975-06-15'), ('Zotov', 'Mikhail', 'Urievich', 'M', 110000, ‘1978-01-20'), ('Ivanov', 'Ivan', 'Maksimovich', 'M', 90000, '1999-11-11', 7, 178), ('Stepanova', 'Alisa', 'Igorevna', 'F', 75000, '1981-01-12', 5, 169), ('Zakharov', 'Zahar', 'Olegovich', 'M', 77000, '1985-10-20', 10, 185), ('Kuzmin', 'Danil', 'Viktorovich', 'M', 55000, '1993-02-11', 6, 170),
('Andreeva', 'Tatyana', 'Vladilenovna', 'F', 90000, '1978-02-13', 2, 174), ('Koshelev', 'Pavel', 'Aleksandovich', 'M', 93000, '1969-08-21', 1, 181);
INSERT INTO theaters(title, director_id)
VALUES ('The best theater or nothing', 5);
INSERT INTO position_worker(position_id, worker_id, theater_id) VALUES (3, 7, 1),
(1, 8, 1), (2, 3, 1), (4, 7, 1), (4, 5, 1), (5, 6, 1), (6, 8, 1), (6, 2, 1), (6, 5, 1), (2, 1, 1), (3, 2, 1), (4, 3, 1), (5, 4, 1), (6, 6, 1);
Был подготовлен код на языке Python для выполнения подключения к БД и запроса данных из таблиц. В результате требуется получить распределение количества работников по каждой из должностей.
import pandas as pd
import matplotlib.pyplot as plt import psycopg2
conn = psycopg2.connect(dbname='theatre', user='root', password='root', host='localhost')

cursor = conn.cursor()
cursor.execute('SELECT p.name AS name, count(p.name) AS count FROM positions p '
'LEFT JOIN position_worker pw ON pw.position_id =
p.id '
'LEFT JOIN workers w ON w.id = pw.worker_id ' 'GROUP BY p.name')
rows = cursor.fetchall() cursor.close() conn.close()
df = pd.DataFrame(rows) print(df)
plt.figure()
plt.tick_params(axis='x', rotation=20) plt.bar(df[0], df[1])
plt.show()
В результате была получена диаграмма, изображенная на рисунке 2.
Рисунок 2 - Количество работников на каждой из позиций

Был выполнен запрос на подсчет работников для каждого из театров. Предварительно была произведена вставка записей в таблицы. Результат представлен на рисунке 3.
INSERT INTO theaters(title, director_id)
VALUES ('Mariinsky', 2), ('Mikhailovskiy', 5);
INSERT INTO position_worker(position_id, worker_id, theater_id)
VALUES (3, 7, 2), (1, 8, 2), (2, 3, 2), (4, 7, 2), (4, 5, 3), (5, 6, 3), (6, 8, 3), (6, 2, 3), (6, 5, 3), (2, 1, 3), (3, 2, 3), (4, 3, 3), (5, 4, 2), (6, 6, 3);
Рисунок 3 - Результат выполнения запроса с построенным графиком
Листинг программы: import pandas as pd
import matplotlib.pyplot as plt import psycopg2
conn = psycopg2.connect(dbname='theatre', user='root', password='root', host='localhost')
cursor = conn.cursor()

cursor.execute('SELECT t.title AS title, count(t.title) AS count FROM position_worker pw '
'LEFT JOIN theaters t ON t.id = pw.theater_id ' 'GROUP BY t.title')
rows = cursor.fetchall() cursor.close() conn.close()
df = pd.DataFrame(rows) print(df)
plt.figure() plt.tick_params(axis='x', rotation=0) plt.bar(df[0], df[1])
plt.show()
Добавлены данные в таблицы с данными, на основе которых будет построена круговая диаграмма.
INSERT INTO achievements(name)
VALUES ('Лучший работник'), ('Трудолюбивый работник'), ('Голос коллектива'), ('Организованный работник'), ('Самостоятельный работник'), ('Пунктуальный работник');
INSERT INTO achievement_worker(achievement_id, worker_id)
VALUES (3, 7), (1, 8), (2, 3), (3, 2), (4, 5), (5, 6), (6, 8), (1, 2), (2, 5), (3, 1), (4, 2), (5, 3), (6, 4), (6, 6);
Листинг программы: import pandas as pd
import matplotlib.pyplot as plt import psycopg2
conn = psycopg2.connect(dbname='theatre', user='root', password='root', host='localhost')
cursor = conn.cursor()
cursor.execute('SELECT w.first_name || \' \' || w.last_name || \' \' || COALESCE(w.patronymic, \'\') AS name, count(w.*) AS count FROM

workers w '
'LEFT JOIN achievement_worker aw ON aw.worker_id = w.id
'
'GROUP BY w.first_name || \' \' || w.last_name || \' \' || COALESCE(w.patronymic, \'\')')
rows = cursor.fetchall() cursor.close() conn.close()
df = pd.DataFrame(rows) titles = df[0]
counts = df[1]
plt.figure(figsize=(10, 7))
plt.pie(counts, labels=titles, autopct='%1.1f%%', startangle=140) plt.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.title("Распределение достижений")
plt.show()
Результат выполнения представлен на рисунке 4.
Рисунок 4 - Распределение достижений между работниками
Вывод
В результате проделанной работы были изучены варианты построения графиков разного вида с использованием библиотек pandas, pyplot. Также изучен и опробован вариант работы с БД PostgreSQL с использованием библиотеки psycopg2.
Список использованных источников
1)Методические указания по выполнению лабораторной работы: https://pro.guap.ru/inside/student/tasks/d17ce8e9dc316178aa73693bf63f938e/download
2)Документаци по установке библиотеки для работы PostgreSQL: https://khashtamov.com/ru/postgresql-python-psycopg2/
3)Документация по работе с библиотекой psycopg2: https://metanit.com/python/database/2.1.php
4)Документация по работе с plot: https://www.geeksforgeeks.org/plot-a-pie-chart-in-python-using-matplotlib/