
6 семестр / БД7
.docxГУАП
КАФЕДРА № 41
ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ
ПРЕПОДАВАТЕЛЬ
старший преподаватель |
|
|
|
Б.К. Акопян |
должность, уч. степень, звание |
|
подпись, дата |
|
инициалы, фамилия |
ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №7 |
ВИЗУАЛИЗАЦИЯ ДАННЫХ ИЗ СУБД POSTGRESQL В PYTHON |
по курсу: БАЗЫ ДАННЫХ |
|
РАБОТУ ВЫПОЛНИЛ
СТУДЕНТ ГР. № |
|
|
|
|
|
|
|
|
|
|
подпись, дата |
|
инициалы, фамилия |
Санкт-Петербург 2024
Цель работы:
Произвести связь базы данных в PostgreSQL и Python, изучить операции по манипулированию с данными БД, выполнить анализ данных в БД с помощью визуализации в Python.
Ход работы:
Вариант задания представлен на рисунке 1.
Рисунок 1 – Вариант задания
Первые два графика по заданию представлены на рисунках 2, 3. Для их реализации использовались запросы с JOIN и GROUP BY.
Рисунок 2 – Максимальная зарплата по отделу менеджера
У менеджера Steven King в отделе имеется сотрудник с самой большой ЗП – 24000.
Рисунок 3 – Минимальная зарплата по отделу
Самая низкая минимальная ЗП в отделе Shipping.
На рисунках 4, 5 представлены модификации первых двух графиков. Были созданы и вызваны функции для получения результата в ограниченном пользователем диапазоне.
Рисунок 4 – Максимальная зарплата по отделу менеджера в диапазоне от 10000 до 50000
Рисунок 5 – Минимальная зарплата по отделу в диапазоне от 10000 до 50000
На рисунке 6 представлен график с использованием таблицы locations.
Рисунок 6 – Число работников в городах
Больше трети сотрудников располагаются в трех городах: Whitehorse, Hiroshima, Seattle.
На рисунке 7 представлен вывод датафреймов, использующихся для построения графиков в Python. Полный листинг кода расположен в приложении.
Рисунок 7 – Вывод в Python
Вывод:
В ходе выполнения лабораторной работы были улучшены навыки работы с взаимодействием Python и PostgreSQL, с помощью библиотеки matplotlib построены столбчатая диаграмма, горизонтальная столбчатая диаграмма и круговая диаграмма. Библиотека psycopg2 позволила осуществить подключение к БД, реализовать процедуры для выборки с заданным пользователем диапазоном, перенос таблиц в датафреймы Python для построения графиков.
Список используемых источников:
1. A.В. Аграновский, В.В. Боженко, Е.Л. Турнецкая. - Учебно-методическое пособие «Разработка и администрирование базы данных с открытым исходным кодом» ‒ СПб.: ГУАП, 2022
2. Документация PostgreSQL, URL: https://www.postgresql.org/docs/ (Дата обращения 26.02.2024).
3. Документация Python, URL: https://docs.python.org/3/ (Дата обращения 26.02.2024).
ПРИЛОЖЕНИЕ
Листинг кода Python:
import pandas as pd
import psycopg2
import matplotlib.pyplot as plt
connection = psycopg2.connect(database="students",
user="postgres",
password="root",
host="127.0.0.1",
port="5432")
cursor = connection.cursor()
with connection.cursor() as cursor:
# 1
sql = '''
SELECT
CONCAT(e.last_name,' ', e.first_name) AS manager,
MAX(e.salary) AS max_dept_salary
FROM
employees e
JOIN
departments d ON e.employee_id = d.manager_id
GROUP BY
manager
;
'''
cursor.execute(sql)
rows = cursor.fetchall()
df_first = pd.DataFrame(rows)
# 2
sql = '''
SELECT
d.department_name AS department,
MIN(e.salary) AS min__dept_salary
FROM
departments d
JOIN
employees e ON d.department_id = e.department_id
GROUP BY
d.department_name
;
'''
cursor.execute(sql)
rows = cursor.fetchall()
df_second = pd.DataFrame(rows)
# 1 с модификацией
sql = '''
CREATE OR REPLACE FUNCTION get_managers_in_salary_range(min INT, max INT)
RETURNS TABLE (
manager TEXT,
max_dept_salary INT
) AS $$
SELECT
CONCAT(e.last_name,' ', e.first_name) AS manager,
MAX(e.salary) AS max_dept_salary
FROM
employees e
JOIN
departments d ON e.employee_id = d.manager_id
WHERE
e.salary BETWEEN min AND max
GROUP BY
manager
;
$$ LANGUAGE SQL
;
SELECT * FROM get_managers_in_salary_range(10000, 50000);
'''
cursor.execute(sql)
rows = cursor.fetchall()
df_first_mod = pd.DataFrame(rows)
# 2 с модификацией
sql = '''
CREATE OR REPLACE FUNCTION get_dept_in_salary_range(min INT, max INT)
RETURNS TABLE (
department_name TEXT,
min_dept_salary INT
) AS $$
SELECT
d.department_name AS department,
MIN(e.salary) AS min__dept_salary
FROM
departments d
JOIN
employees e ON d.department_id = e.department_id
WHERE
e.salary BETWEEN min AND max
GROUP BY
d.department_name
;
$$ LANGUAGE SQL
;
SELECT * FROM get_dept_in_salary_range(10000, 50000);
'''
cursor.execute(sql)
rows = cursor.fetchall()
df_second_mod = pd.DataFrame(rows)
# 5
sql = '''
SELECT
l.city,
COUNT(e.employee_id) AS number_of_employees
FROM
locations l
LEFT JOIN
employees e ON l.location_id = e.location_id
GROUP BY
l.location_id, l.city
;
'''
cursor.execute(sql)
rows = cursor.fetchall()
df_cities = pd.DataFrame(rows)
connection.close()
# 1
print('Максимальная зарпалата по отделу менеджера')
print(df_first,"\n")
fig, ax = plt.subplots()
bars = plt.bar(df_first[0],df_first[1])
ax.bar_label(bars)
ax.spines[['right', 'top']].set_visible(False)
plt.title('Максимальная зарпалата по отделу менеджера')
# 2
print('Минимальная зарплата по отделу')
print(df_second,"\n")
fig, ax = plt.subplots()
bars = plt.bar(df_second[0], df_second[1])
ax.bar_label(bars)
ax.spines[['right', 'top']].set_visible(False)
plt.title('Минимальная зарплата по отделу')
# 1 с модификацией
print('Максимальная зарпалата по отделу менеджера в диапазоне')
print(df_first_mod,"\n")
fig, ax = plt.subplots()
bars = plt.barh(df_first_mod[0], df_first_mod[1], color='orange')
ax.bar_label(bars)
ax.spines[['right', 'top', 'bottom']].set_visible(False)
plt.title('Максимальная зарпалата по отделу менеджера в диапазоне')
# 2 с модификацией
print('Минимальная зарплата по отделу в диапазоне')
print(df_second_mod,"\n")
fig, ax = plt.subplots()
bars = plt.barh(df_second_mod[0], df_second_mod[1], color='green')
ax.bar_label(bars)
ax.spines[['right', 'top', 'bottom']].set_visible(False)
plt.title('Минимальная зарплата по отделу в диапазоне')
# 5
print('Число работников в городах')
print(df_cities,"\n")
plt.figure()
def make_autopct(values):
def my_autopct(pct):
total = sum(values)
val = int(round(pct*total/100.0))
return '{p:.0f}% ({v:d})'.format(p=pct,v=val)
return my_autopct
plt.pie(df_cities[1], labels=df_cities[0], autopct=make_autopct(df_cities[1]))
plt.textprops={'size': 'x-large'}
plt.title('Число работников в городах')
plt.show()