Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2 / кр3

.docx
Скачиваний:
1
Добавлен:
16.05.2025
Размер:
440.28 Кб
Скачать

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ

федеральное государственное автономное образовательное учреждение высшего образования

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»

Кафедра 41

ПРЕПОДАВАТЕЛЬ

Доцент, канд. техн. наук

Е. Л. Турнецкая

должность, уч. степень, звание

подпись, дата

инициалы, фамилия

Контрольная работа №3

Связь СУБД PostgreSQL и Python.

по курсу: Базы данных

СТУДЕНТКА ГР. №

Z0411

25.01.24

М. В. Карелина

номер группы

подпись, дата

инициалы, фамилия

Номер студенческого билета: 2020/3477

Санкт-Петербург

2024

Цель работы: произвести связь базы данных в PostgreSQL и Python, изучить операции по манипулированию с данными БД, а также созданию простейших пользовательских функций.

Порядок выполнения работы:

1. Использовать БД, созданную в предыдущей ЛР (employees, departments, jobs). Обязательно предоставить схему данных в отчете.

2. Осуществить связь Python и БД в PostgreSQL.

3. Создать новую таблицу locations, по примеру методических указаний. Заполнить таблицу данными:

INSERT INTO locations VALUES ( 1,'Roma', '00989');

INSERT INTO locations VALUES ( 2,'Venice','10934');

INSERT INTO locations VALUES ( 3,'Tokyo', '1689');

INSERT INTO locations VALUES ( 4,'Hiroshima','6823');

INSERT INTO locations VALUES ( 5,'Southlake', '26192');

INSERT INTO locations VALUES ( 6,'South San Francisco', '99236');

INSERT INTO locations VALUES ( 7,'South Brunswick','50090');

INSERT INTO locations VALUES ( 8,'Seattle','98199');

INSERT INTO locations VALUES ( 9,'Toronto','M5V 2L7',);

INSERT INTO locations VALUES ( 10,'Whitehorse','YSW 9T2');

4. Добавить в таблицу с сотрудниками location_id, добавить связь с таблицей locations, заполнить столбец location_id данными. В отчете описать, каким способом было выполнено задание, приложить скриншоты результатов, в том числе обновленную схему данных.

5. Выполнить 3 запроса SELECT в Python, предоставить скриншоты результатов и текстовое пояснение:

На оценку 5 выполняете запросы по таблице 1 (страница 6 методических указаний). Третий запрос на ваш выбор, но необходимо задействовать новую таблицу locations.

6. Создать функцию select_data в СУБД PostgreSQL (см. Методические указания 4 пункт), продемонстрировать результат работы. Вызвать функцию select_data в Python, продемонстрировать результат. Создать функцию select_data1 в скрипте Python, продемонстрировать результат вызова этой функции в СУБД PostgreSQL.

7. Задание на оценку 5. Если данное задание не выполнено итоговая оценка снижается на 1 балл: Создать собственную пользовательскую функцию в СУБД PostgreSQL, используя более сложные SQL-запросы (например, с применением агрегатных функций и связью нескольких таблиц), продемонстрировать результат работы. Создать эту же функцию через скрипт Python.

8. Выполнить любую визуализацию в Python. Графики должны быть наглядными, график обязательно должен иметь заголовок, подписи к осям, а также отображать показательные значения (например, должность, а не id должности). К полученным графикам необходимо дать пояснения, прокомментировать результаты.

Вариант 7.

В данной работе будет использована БД по работникам компании и схема данных, реализованная в прошлой работе (Рис. 1).

Рисунок 1 - Схема данных hr

Нужно открыть предпочитаемую IDE, в данной работе это PyCharm. Библиотека pandas уже установлена, так что надо установить библиотеку psycopg2 через pip install.

После установки можно установить соединение Python с БД в PostgreSQL.

import pandas as pd import psycopg2 # Подключение к базе данных: connection = psycopg2.connect(database="students", # название базы данных user="postgres", password="admin", host="127.0.0.1", port="5432")

Вывод данные о соединении и версии СУБД (Рис. 2):

cursor = connection.cursor() # курсор для выполнения операций с БД print(connection.get_dsn_parameters(), "\n") # вывод свойства соединения cursor.execute("SELECT version();") # выполнение запроса к БД version_ps = cursor.fetchone() # получение результата запроса print("Вы подключены к - ", version_ps, "\n")

Рисунок 2 - Данные о соединении и версии СУБД

Выполнение запрос на выборку данных из таблицы с работами (Рис. 3):

sql = "SELECT * FROM jobs " # запрос SQL df = pd.read_sql_query(sql, connection) print(df)

Рисунок 3 - Результат выполнения SQL запроса

Была создана новая таблица locations.

cursor.execute('''CREATE TABLE if not exists locations (location_id int PRIMARY KEY, city varchar(30), postal_code varchar(12) ); ''')

Проверка, что таблица появилась в СУБД PostgreSQL (Рис. 4):

Рисунок 4 - Создание новой таблицы

Заполнение таблицу данными и выведение результата (Рис. 5):

cursor.execute('''INSERT INTO locations VALUES (1, 'Roma', '00989'), (2,'Venice','10934'), (3,'Tokyo', '1689'), (4,'Hiroshima','6823'), (5,'Southlake', '26192'), (6,'South San Francisco', '99236'), (7,'South Brunswick','50090'), (8,'Seattle','98199'), (9,'Toronto','M5V 2L7'), (10,'Whitehorse','YSW 9T2'); ''') connection.commit() table_locations = pd.read_sql_query("SELECT * FROM locations ", connection) print(table_locations)

Рисунок 5 - Заполненная таблица locations

В таблицу с сотрудниками была добавлена колонка location_id, также была осуществлена связь с таблицей locations и заполнен данными столбец location_id.

cursor.execute('''ALTER TABLE employees ADD COLUMN location_id INTEGER references locations(location_id);''') connection.commit() cursor.execute('''UPDATE employees SET location_id = floor(random() * 10 + 1);''') connection.commit()

Новая схема данных и заполненная таблица employees на Рис. 6.

Рисунок 6 - Схема данных

Теперь необходимо выполнить три запроса SELECT в Python.

  1. Найти сотрудника со второй по счёту минимальной зарплатой. Листинг запроса представлен в листинге 1 и результат на рисунке 7.

Листинг 1: Нахождение сотрудника со второй по счёту минимальной зарплатой

query = ("SELECT e.first_name, e.last_name, e.salary " "FROM hr.employees e " "ORDER BY e.salary " "OFFSET 1 " "LIMIT 1") cursor.execute(query) connection.commit() rows = cursor.fetchall() df = pd.DataFrame(rows, columns=['first_name', 'last_name', 'salary']) print(df)

Рисунок 7 – Результат выполнения запроса

  1. Выяснить, сколько фондовых менеджеров (Stock_manager) работают в отделе

перевозок (Shipping). Листинг запроса представлен в листинге 2 и результат на рисунке 8.

Листинг 2: Выяснить, сколько фондовых менеджеров (Stock_manager) работают в отделе перевозок (Shipping)

query = ("SELECT d.department_name, j.job_title, COUNT(*) AS EmployeesCount " "FROM hr.employees e " "JOIN hr.departments d ON e.department_id = d.department_id " "JOIN hr.jobs j ON e.job_id = j.job_id " "WHERE d.department_name = 'Shipping' AND j.job_title = 'Stock Manager' " "GROUP BY d.department_name, j.job_title") cursor.execute(query) connection.commit() rows = cursor.fetchall() df = pd.DataFrame(rows, columns=['department_name', 'j.job_title', 'EmployeesCount']) print(df)

Рисунок 8 – Результат выполнения запроса

  1. Данный запрос должен быть на наш выбор, но необходимо задействовать новую таблицу locations. Создадим запрос который показывает среднюю зарабротную плату в зависимости от города. Листинг запроса представлен в листинге 3 и результат на рисунке 9.

Листинг 3: Выяснить, среднюю заработную плату в зависимости от города.

create_column_query = "ALTER TABLE locations ADD COLUMN IF NOT EXISTS avg_salary NUMERIC" cursor.execute(create_column_query) connection.commit()

average_salary_query = ("UPDATE locations l " "SET avg_salary = (SELECT AVG(e.salary) " " FROM employees e " " WHERE e.location_id = l.location_id) " "WHERE EXISTS (SELECT 1 FROM employees WHERE location_id = l.location_id)") cursor.execute(average_salary_query) connection.commit() locations_query = "SELECT * FROM locations" cursor.execute(locations_query) rows = cursor.fetchall() locations_df = pd.DataFrame(rows, columns=['location_id','city','postal_code','avg_salary']) # Print the result print(locations_df)

Рисунок 7 - Результат выполнения запроса

Теперь необходимо создать функцию select_data в СУБД PostgreSQL, продемонстрировать результат работы. Вызвать функцию select_data в Python, продемонстрировать результат. Создать функцию select_data1 в скрипте Python, продемонстрировать результат вызова этой функции в СУБД PostgreSQL.

Функция select_data в PostgreSQL на вход получает код отдела и выводит информацию из таблицы departments, фильтруя данные по коду отдела.

CREATE FUNCTION select_data(id_dept int) RETURNS SETOF departments AS $$

SELECT * FROM departments WHERE departments.department_id > id_dept;

$$ LANGUAGE SQL;

SELECT * FROM select_data(30);

Результат вывода в DBeaver (Рис. 10).

Рисунок 10 - Создание функции

Теперь вызов созданной функции из скрипта в Python (Рис. 11):

cursor.callproc('select_data', [20, ]) # вызов функции (название из PostgreSQL) result = cursor.fetchall() # получение результатов result_proc = pd.DataFrame(result) # создание датафрейма с результатом print(result_proc)

Рисунок 11 - Выполнение функции в Python

Теперь необходимо создать функцию select_data1, аналогичную функции выше в скрипте Python и внести изменения в БД в PostgreSQL.

postgresql_func = """ CREATE OR REPLACE FUNCTION select_data1(id_dept int) RETURNS SETOF departments AS $$ SELECT * FROM departments WHERE departments.department_id > id_dept; $$ LANGUAGE SQL; """ cursor.execute(postgresql_func) # выполнение запроса connection.commit() #внесение изменений в БД connection.close() # закрытие соединения cursor.close() # закрытие cursor

Отображение обеих функций в PostgreSQL и вызов функции select_data1 на Рис. 12.

Рисунок 12 – Функция select_data

Теперь необходимо создать пользовательскую функцию. Данная функция показывает суммарную заработную плату в зависимости от введённого номера города. Листинг запроса представлен в листинге 4 и результат на рисунке 13.

Листинг 4: Выяснить, суммарную среднюю заработную плату в зависимости от города.

CREATE OR REPLACE FUNCTION location_salary_sum_with_city(id_loc int)

RETURNS TABLE(location_id int, city text, location_salary_sum double precision) AS $$

SELECT l.location_id, l.city, sum(e.salary)::double precision as location_salary_sum

FROM hr.employees e

JOIN hr.locations l on e.location_id = l.location_id

WHERE e.location_id = id_loc

GROUP BY l.location_id, l.city;

$$ LANGUAGE SQL;

Рисунок 13 - Результат выполнения функции в DBeaver

Код для создания и вызова такой же функции через скрипт Python представлен в листинге 5 и 6. Результат выполнения представлен на рисунке 14.

Листинг 5:

cursor.execute('CREATE OR REPLACE FUNCTION hr.location_salary_sum_with_city1(id_loc int) ' 'RETURNS TABLE(location_id int, city text, location_salary_sum double precision) ' 'AS $$ SELECT l.location_id, l.city, sum(e.salary)::double precision as location_salary_sum ' 'FROM hr.employees e ' 'JOIN hr.locations l on e.location_id = l.location_id ' 'WHERE e.location_id = id_loc ' 'GROUP BY l.location_id, l.city; $$ LANGUAGE SQL;') connection.commit() # внесение изменений в бд connection.close() cursor.close()

Листинг 6:

cursor.callproc('hr.location_salary_sum_with_city1', [5]) result = cursor.fetchall() result_proc = pd.DataFrame(result) print(result_proc) connection.commit() # внесение изменений в бд connection.close() cursor.close()

Рисунок 14 – Результат выполнения функции в Python

Отображение обеих функций в PostgreSQL представлен на рисунке 15.

Рисунок 15 - Функции

На финальном этапе необходимо провести визуализацию средствами Python.

Код визуализации запроса сравнения средней зарплаты по городам представлен в листинге 7, результат визуализации представлен на рисунке 16.

Листинг 7: Сравнения средней зарплаты по городам

query = """ SELECT city, avg_salary FROM locations; """ # Выполнение SQL-запроса cursor.execute(query) # Получение результатов results = cursor.fetchall() # Создание DataFrame с результатами df = pd.DataFrame(results, columns=['Город', 'Средняя зарплата']) # Закрытие курсора и соединения cursor.close() connection.close() # Построение графика plt.figure(figsize=(10, 6)) plt.bar(df['Город'], df['Средняя зарплата']) plt.xlabel('Город') plt.ylabel('Средняя зарплата') plt.title('Средняя зарплата по городам') plt.xticks(rotation=45) plt.tight_layout() plt.show()

Рисунок 16 – Результат запроса с визуализацией

Вывод

В результате выполнения лабораторной работы была создана и заполнена новая таблица locations, добавлен новый столбец location_id в таблицу employees и установлена связь между таблицами employees и locations используя скрипт Python. Также было написано три запроса по заданию и создано четыре функции используя менеджер баз данных и Python. И в итоге выполнена визуализация запроса для базы данных students.

Соседние файлы в папке 2