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

ГУАП

КАФЕДРА № 41

ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ

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

старший преподаватель

Б.К. Акопян

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

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

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

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №6

СВЯЗЬ СУБД POSTGRESQL И PYTHON

по курсу: БАЗЫ ДАННЫХ

РАБОТУ ВЫПОЛНИЛ

СТУДЕНТ ГР. №

4116

С.А. Степченко

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

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

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

Цель работы:

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

Вариант 21

Рисунок 1- Индивидуальный вариант

Ход работы:

Произведено соединение Python с БД в PostgreSQL, с помощью connection.get_dsn_parameters() выводятся параметры соединения. (Рисунок 2).

Листинг 1. Соединение Python с БД в PostgreSQL

import pandas as pd

import psycopg2

# Подключение к базе данных:

connection = psycopg2.connect(database="students",

user="postgres",

password="12345",

host="127.0.0.1",

port="5432")

cursor = connection.cursor()

print(connection.get_dsn_parameters(), "\n")

cursor.execute("SELECT version();")

version_ps = cursor.fetchone()

print("Вы подключены к - ", version_ps, "\n")

cursor.close()

Рисунок 2 – Параметры соединения с БД

Выполнен запрос на выборку данных с помощью read_sql_query (Рисунок 3).

Листинг 2. Запрос на выборку

sql = "SELECT * FROM jobs "

df = pd.read_sql_query("SELECT * FROM jobs ", connection)

print(df)

Рисунок 3- Запрос на выборку из таблицы jobs

Создана новая таблица locations и заполнена данными, результат выведен на экран (Рисунок 4-5).

Листинг 3. Создание таблицы locations, добавление записей и вывод на экран

cursor.execute('''CREATE TABLE if not exists locations

(location_id int PRIMARY KEY,

city varchar(30),

postal_code varchar(12)

); ''')

cursor.execute(

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

)

connection.commit()

table_locations = pd.read_sql_query("SELECT * FROM locations ",connection)

print(table_locations)

Рисунок 4- Вывод таблицы locations в Python

Рисунок 5 – Таблица locations в Dbeaver

В таблицу добавлены новые записи (Рисунок 6).

Листинг 4. Добавление новых записей

cursor.execute(

'''INSERT INTO locations VALUES

(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()

Рисунок 6 – Добавление новых записей

В таблицу с сотрудниками добавлен столбец location_id. Для заполнения нового столбца создан курсор, проходящий по всем записям в таблице и вставляющий в location_id случайное значение из таблицы locations (Рисунок 7).

Листинг 5. Добавление и заполнение столбца location_id

# Добавление столбца

cursor.execute("ALTER TABLE employees ADD COLUMN IF NOT EXISTS location_id INT;")

# Установление связи между таблицами

cursor.execute("""

ALTER TABLE employees

ADD CONSTRAINT fk_location_id

FOREIGN KEY (location_id)

REFERENCES locations(location_id);

""")

# Получение списка всех location_id из таблицы locations

cursor.execute("SELECT location_id FROM locations;")

location_ids = [row[0] for row in cursor.fetchall()]

# Обновление столбца location_id в таблице employees случайными значениями

cursor.execute("SELECT employee_id FROM employees WHERE location_id IS NULL;")

employee_ids = cursor.fetchall()

for emp_id in employee_ids:

# Выбор случайного location_id из списка

random_location_id = random.choice(location_ids)

# Обновление записи сотрудника случайным location_id

cursor.execute(

"UPDATE employees SET location_id = %s WHERE employee_id = %s;",

(random_location_id, emp_id[0])

)

Рисунок 7 – Заполненный location_id

На рисунке 8 представлена обновленная схема данных.

Рисунок 8 – Обновленная схема данных

Реализованы три запроса. Первый запрос выводит сотрудника, фамилия которого состоит более чем из одного слова.

Листинг 6. Первый запрос

employee = pd.read_sql_query("SELECT * FROM employees WHERE last_name LIKE '%% %%';", connection)

print(employee)

connection.commit()

Рисунок 9- Результат первого запроса

Второй запрос находит минимальные зарплаты по отделам, и выводит те, которые больше 10000.

Листинг 7. Второй запрос

query = """

SELECT department_id, MIN(salary) as min_salary

FROM employees

WHERE salary > 10000

GROUP BY department_id;

"""

min_salaries_above_10000 = pd.read_sql_query(query, connection)

print(min_salaries_above_10000)

Рисунок 10 – Результат второго запроса

Третий запрос выводит количество сотрудников в каждом городе (Рисунок 11).

Листинг 7. Третий запрос

query = """

SELECT l.city, COUNT(e.employee_id) AS number_of_employees

FROM employees e

JOIN locations l ON e.location_id = l.location_id

GROUP BY l.city;

"""

number_of_employees = pd.read_sql_query(query, connection)

print(number_of_employees)

Рисунок 11- Результат третьего запроса

Создана и выполнена функция select_data в PostgreSQL, функция получает код отдела и выводит информацию из таблицы departments, выводятся отделы, у которых код больше введенного (Рисунок 12).

Листинг 8. Функция select_data

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

SELECT * FROM departments WHERE departments.department_id > id_dept;

$$ LANGUAGE SQL;

Рисунок 12 – Результат работы select_data

Функция select_data была вызвана в python (Рисунок 13).

Листинг 9. Вызов функции select_data в python

cursor.callproc('select_data',[30,])

result = cursor.fetchall()

result_proc = pd.DataFrame(result)

print(result_proc)

Рисунок 13 – Вызов функции select_data в Python

Функция select_data1 создана в Python и выполнена в PostgreSQL (Рисунок 14.

Листинг 10. Функции select_data1 в python

postgresql_func = """

CREATE OR REPLACE FUNCTION select_data1(id_dept int) RETURNS SETOF departments AS $$

SELECT * FROM departments WHERE departments.department_id >

id_dept;

"""

cursor.execute(postgresql_func)

connection.commit()

Рисунок 14 – Вызов функции select_data1 в PostgreSQL с параметром 20

Реализована функция, выводящая среднюю зарплату сотрудников в департаментах (Рисунок 15)

Листинг 11. Запрос на вывод средней зарплатны сотрудников в департаментах в PostgreSQL

SELECT d.department_name, ROUND(AVG(e.salary), 1)

FROM departments d

JOIN employees e ON d.department_id = e.department_id

GROUP BY d.department_name

ORDER BY ROUND(AVG(e.salary), 1);

Рисунок 15 – Результат работы запроса в PostgreSQL

Запрос написан в Python (Рисунок 16).

Листинг 12. Запрос на вывод средней зарплатны сотрудников в департаментах в Python

query = """

SELECT d.department_name, ROUND(AVG(e.salary), 1)

FROM departments d

JOIN employees e ON d.department_id = e.department_id

GROUP BY d.department_name

ORDER BY ROUND(AVG(e.salary), 1);

"""

average_salary = pd.read_sql_query(query, connection)

print(average_salary)

Рисунок 16 – Результат работы запроса в Python

Вывод:

В ходе выполнения лабораторной работы произведено управление БД PostgreSQL с помощью Python. Для соединения с БД использовалась библиотека psycopg2, для работы с данными библиотека pandas. Реализованы запросы на нахождение сотрудника, фамилия которого состоит более чем из одного слова; на подсчет минимальной зарплаты по отделам, которая больше 10000; запрос на подсчет количества сотрудников в каждом городе и запрос на вывод средней зарплатны сотрудников в департаментах.

Список используемых источников:

1. A.В. Аграновский, В.В. Боженко, Е.Л. Турнецкая. - Учебно-методическое пособие «Разработка и администрирование базы данных с открытым исходным кодом» ‒ СПб.: ГУАП, 2022

2. Документация PostgreSQL, URL: https://www.postgresql.org/docs/

3. Документация Python, URL: https://docs.python.org/3/

ПРИЛОЖЕНИЕ

import pandas as pd

import psycopg2

import random

# Подключение к базе данных:

connection = psycopg2.connect(database="students",

user="postgres",

password="12345",

host="127.0.0.1",

port="5432")

cursor = connection.cursor()

print(connection.get_dsn_parameters(), "\n")

cursor.execute("SELECT version();")

version_ps = cursor.fetchone()

print("Вы подключены к - ", version_ps, "\n")

sql = "SELECT * FROM jobs "

df = pd.read_sql_query("SELECT * FROM jobs ", connection)

print(df)

cursor.execute('''CREATE TABLE if not exists locations

(location_id int PRIMARY KEY,

city varchar(30),

postal_code varchar(12)

); ''')

cursor.execute(

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

)

cursor.execute(

'''INSERT INTO locations VALUES

(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');

'''

)

# 1. Добавление столбца location_id в таблицу employees:

cursor.execute("ALTER TABLE employees ADD COLUMN IF NOT EXISTS location_id INT;")

# 2. Установление связи между таблицами employees и locations:

cursor.execute("""

ALTER TABLE employees

ADD CONSTRAINT fk_location_id

FOREIGN KEY (location_id)

REFERENCES locations(location_id);

""")

# Получение списка всех location_id из таблицы locations

cursor.execute("SELECT location_id FROM locations;")

location_ids = [row[0] for row in cursor.fetchall()]

# Обновление столбца location_id в таблице employees случайными значениями из списка location_ids

cursor.execute("SELECT employee_id FROM employees WHERE location_id IS NULL;")

employee_ids = cursor.fetchall()

for emp_id in employee_ids:

# Выбор случайного location_id из списка

random_location_id = random.choice(location_ids)

# Обновление записи сотрудника случайным location_id

cursor.execute(

"UPDATE employees SET location_id = %s WHERE employee_id = %s;",

(random_location_id, emp_id[0])

)

#первый запрос

employee = pd.read_sql_query("SELECT * FROM employees WHERE last_name LIKE '%% %%';", connection)

print(employee)

# второй запрос

query = """

SELECT department_id, MIN(salary) as min_salary

FROM employees

WHERE salary > 10000

GROUP BY department_id;

"""

min_salaries_above_10000 = pd.read_sql_query(query, connection)

print(min_salaries_above_10000)

# третий запрос

query = """

SELECT l.city, COUNT(e.employee_id) AS number_of_employees

FROM employees e

JOIN locations l ON e.location_id = l.location_id

GROUP BY l.city;

"""

number_of_employees = pd.read_sql_query(query, connection)

print(number_of_employees)

#Вызов функции select_data

cursor.callproc('select_data',[30,])

result = cursor.fetchall()

result_proc = pd.DataFrame(result)

print(result_proc)

#Создание функции select_data

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)

#Четвертый запрос

query = """

SELECT d.department_name, ROUND(AVG(e.salary), 1)

FROM departments d

JOIN employees e ON d.department_id = e.department_id

GROUP BY d.department_name

ORDER BY ROUND(AVG(e.salary), 1);

"""

average_salary = pd.read_sql_query(query, connection)

print(average_salary)

connection.commit()

table_locations = pd.read_sql_query("SELECT * FROM locations ",connection)

print(table_locations)

cursor.close()

Соседние файлы в папке БД 3 курс весна