
Лаб. 8 СУБД
.docxЛабораторная работа 8
«Разработка программы на языке С
для работы с базой данных»
import psycopg2 import sys def err_exit(conn): """Функция выхода из программы с сообщением об ошибке""" if conn: conn.close() sys.exit(1) def print_query(conn, query): """Функция печати результата запроса на экран""" try: with conn.cursor() as cursor: cursor.execute(query) rows = cursor.fetchall() if not rows: print("No data retrieved") err_exit(conn) for row in rows: print(" ".join(str(value) for value in row)) except Exception as e: print(f"Error executing query: {e}") err_exit(conn) def main(): try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user="SAB", password="123456", dbname="students" ) print("Connected successfully!") except Exception as e: print(f"Connection to database failed: {e}") err_exit(None) print_query(conn, "SELECT * FROM student LIMIT 5;") conn.close() if __name__ == "__main__": main()
\
import psycopg2 from psycopg2 import extensions def find_students_by_ID_unsafe(conn, st_id, f_name): query = f""" SELECT SURNAME, NAME, FIELD_NAME, MARK FROM STUDENT S JOIN PUBLIC.FIELD_COMPREHENSION F_C ON S.STUDENT_ID = F_C.STUDENT_ID JOIN PUBLIC.FIELD F ON F.FIELD_ID = F_C.FIELD WHERE S.STUDENT_ID = {st_id} AND F.FIELD_NAME = '{f_name}' """ cursor = conn.cursor() try: cursor.execute(query) rows = cursor.fetchall() if len(rows) == 0: print("No data retrieved") return for row in rows: print(" ".join(str(v) for v in row)) except Exception as e: print(f"Error: {e}") finally: cursor.close() try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user="SAB", password="123456", dbname="students" ) conn.set_isolation_level(extensions.ISOLATION_LEVEL_AUTOCOMMIT) print("Connected successfully!") st_id = int(input("Enter student ID number: ")) f_name = input("Enter field name: ") find_students_by_ID_unsafe(conn, st_id, f_name) except Exception as e: print(f"Connection error: {e}") finally: if conn: conn.close()
import psycopg2 def find_students_by_ID(conn, st_id, f_name): query = """ SELECT SURNAME, NAME, FIELD_NAME, MARK FROM STUDENT S JOIN PUBLIC.FIELD_COMPREHENSION F_C ON S.STUDENT_ID = F_C.STUDENT_ID JOIN PUBLIC.FIELD F ON F.FIELD_ID = F_C.FIELD WHERE S.STUDENT_ID = %s AND F.FIELD_NAME = %s """ cursor = conn.cursor() try: cursor.execute(query, (st_id, f_name)) rows = cursor.fetchall() if len(rows) == 0: print("No data retrieved") return for row in rows: print(" ".join(str(value) for value in row)) except Exception as e: print(f"Error: {e}") finally: cursor.close() if __name__ == "__main__": try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user="SAB", password="123456", dbname="students" ) print("Connected successfully!") st_id = int(input("Enter student ID number: \n")) f_name = input("Enter field name: \n").strip() find_students_by_ID(conn, st_id, f_name) except Exception as e: print(f"Connection error: {e}") finally: if conn: conn.close()
import psycopg2 def get_average_age_by_group(conn, group_number): query = """ SELECT students_group_number, AVG(EXTRACT(YEAR FROM AGE(current_date, birthday))) AS avg_age FROM student GROUP BY students_group_number HAVING students_group_number = %s ORDER BY students_group_number """ cursor = conn.cursor() try: cursor.execute(query, (group_number,)) rows = cursor.fetchall() if len(rows) == 0: print(f"Нет данных для группы {group_number}.") else: print("Группа | Средний возраст") print("------------------------") for row in rows: group, avg_age = row print(f"{group} | {round(avg_age, 2)}") except Exception as e: print(f"Ошибка: {e}") finally: cursor.close() try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user="SAB", password="123456", dbname="students" ) print("Успешное подключение!") group_number = input("Введите номер группы (например, 'ИБ-21'): ") get_average_age_by_group(conn, group_number) except Exception as e: print(f"Ошибка подключения: {e}") finally: if conn: conn.close()
import psycopg2 def get_students_by_group(conn, group_number): query = f""" select students_group_number, avg(extract(year from age(current_date, birthday))) as avg_age from student group by students_group_number having students_group_number = '{group_number}' order by students_group_number """ cursor = conn.cursor() try: cursor.execute(query) rows = cursor.fetchall() if len(rows) == 0: print(f"Нет данных для группы {group_number}.") return for row in rows: print(" ".join(str(v) for v in row)) except Exception as e: print(f"Ошибка: {e}") finally: cursor.close() try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user="SAB", password="123456", dbname="students" ) print("Подключено успешно!") group_number = input("Введите номер группы (например, 'ИБ-21'): ") get_students_by_group(conn, group_number) except Exception as e: print(f"Ошибка подключения: {e}") finally: if conn: conn.close()
import psycopg2 import re def check_sql_injection(input_str): sql_injections = re.compile( r"(--)|(\s+OR\s+)|(\s+AND\s+)|(;)|(')|(\bDROP\b)|(\bINSERT\b)|(\bUPDATE\b)|(\bDELETE\b)", re.IGNORECASE) # Проверка, есть ли совпадения с инъекциями if sql_injections.search(input_str): return True return False def get_students_by_group(conn, group_number): if check_sql_injection(group_number): print( f"Предупреждение: Ввод содержал подозрительные символы. Пользователь предупреждён о возможной попытке инъекции.") return query = f""" select students_group_number, avg(extract(year from age(current_date, birthday))) as avg_age from student group by students_group_number having students_group_number = '{group_number}' order by students_group_number """ cursor = conn.cursor() try: cursor.execute(query) rows = cursor.fetchall() if len(rows) == 0: print(f"Нет данных для группы {group_number}.") return for row in rows: print(" ".join(str(v) for v in row)) except Exception as e: print(f"Ошибка: {e}") finally: cursor.close() try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user="SAB", password="123456", dbname="students" ) print("Подключено успешно!") group_number = input("Введите номер группы (например, 'ИБ-21'): ") get_students_by_group(conn, group_number) except Exception as e: print(f"Ошибка подключения: {e}") finally: if conn: conn.close()
import psycopg2 def get_average_age_by_group(conn, group_number): query = """ SELECT students_group_number, avg_age FROM student_avg_age_view WHERE students_group_number = %s ORDER BY students_group_number """ cursor = conn.cursor() try: cursor.execute(query, (group_number,)) rows = cursor.fetchall() if len(rows) == 0: print(f"Нет данных для группы {group_number}.") else: print("Группа | Средний возраст") print("------------------------") for row in rows: group, avg_age = row print(f"{group} | {round(avg_age, 2)}") except Exception as e: print(f"Ошибка: {e}") finally: cursor.close() try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user="SAB", password="123456", dbname="students" ) print("Успешное подключение!") group_number = input("Введите номер группы (например, 'ИБ-21'): ") get_average_age_by_group(conn, group_number) except Exception as e: print(f"Ошибка подключения: {e}") finally: if conn: conn.close()
import psycopg2 def get_students_by_group(conn, group_number): # Запрос, использующий представление query = f""" SELECT students_group_number, avg_age FROM student_avg_age_view WHERE students_group_number = '{group_number}' ORDER BY students_group_number """ cursor = conn.cursor() try: cursor.execute(query rows = cursor.fetchall() if len(rows) == 0: print(f"Нет данных для группы {group_number}.") return for row in rows: print(" ".join(str(v) for v in row)) except Exception as e: print(f"Ошибка: {e}") finally: cursor.close() try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user="SAB", password="123456", dbname="students" ) print("Подключено успешно!") group_number = input("Введите номер группы (например, 'ИБ-21'): ") get_students_by_group(conn, group_number) except Exception as e: print(f"Ошибка подключения: {e}") finally: if conn: conn.close()
-- Роль junior с правом только на чтение
CREATE ROLE "AMR junior" WITH LOGIN PASSWORD '654321';
GRANT CONNECT ON DATABASE students TO "AMR junior";
GRANT USAGE ON SCHEMA public TO "AMR junior";
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "AMR junior";
-- Роль admin с полными правами
CREATE ROLE "AMR admin" WITH LOGIN PASSWORD '654321';
GRANT CONNECT ON DATABASE students TO "AMR admin";
GRANT ALL PRIVILEGES ON DATABASE students TO "AMR admin";
GRANT ALL PRIVILEGES ON SCHEMA public TO "AMR admin";
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "AMR admin";
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO "AMR admin";
import psycopg2 from psycopg2 import sql def get_students_by_group(conn, group_number): query = """ SELECT students_group_number, avg_age FROM student_avg_age_view WHERE students_group_number = %s ORDER BY students_group_number """ cursor = conn.cursor() try: cursor.execute(query, (group_number,)) rows = cursor.fetchall() if len(rows) == 0: print(f"Нет данных для группы {group_number}.") else: print("Группа | Средний возраст") print("------------------------") for row in rows: group, avg_age = row print(f"{group} | {round(avg_age, 2)}") except Exception as e: print(f"Ошибка: {e}") finally: cursor.close() def connect_to_database(username, password): try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user=username, password=password, dbname="students" ) print("Подключено успешно!") return conn except Exception as e: print(f"Ошибка подключения: {e}") return None try: username = input("Введите логин: ") password = input("Введите пароль: ") conn = connect_to_database(username, password) if conn: group_number = input("Введите номер группы (например, 'ИБ-21'): ") get_students_by_group(conn, group_number) except Exception as e: print(f"Ошибка: {e}") finally: if conn: conn.close()
import psycopg2 def get_student_grades(conn, student_id): query = """ SELECT S.surname, S.name, F.field_name, FC.mark FROM student S JOIN field_comprehension FC ON S.student_id = FC.student_id JOIN field F ON FC.field = F.field_id WHERE S.student_id = %s """ cursor = conn.cursor() try: cursor.execute(query, (student_id,)) rows = cursor.fetchall() if len(rows) == 0: print(f"Нет данных для студента с ID {student_id}.") else: print("Фамилия | Имя | Предмет | Оценка") print("------------------------------") for row in rows: print(" | ".join(str(v) for v in row)) except Exception as e: print(f"Ошибка: {e}") finally: cursor.close() def update_grade(conn, student_id, field_name, new_mark): get_field_uuid_query = """ SELECT field_id FROM field WHERE field_name = %s """ cursor = conn.cursor() try: cursor.execute(get_field_uuid_query, (field_name,)) field_uuid = cursor.fetchone() if field_uuid is None: print(f"Не найден предмет с названием: {field_name}") return field_uuid = field_uuid[0] update_query = """ UPDATE field_comprehension SET mark = %s WHERE student_id = %s AND field = %s """ cursor.execute(update_query, (new_mark, student_id, field_uuid)) conn.commit() print("Оценка успешно обновлена!") except Exception as e: print(f"Ошибка при обновлении оценки: {e}") finally: cursor.close() def add_grade(conn, student_id, field_name, new_mark): get_field_uuid_query = """ SELECT field_id FROM field WHERE field_name = %s """ cursor = conn.cursor() try: cursor.execute(get_field_uuid_query, (field_name,)) field_uuid = cursor.fetchone() if field_uuid is None: print(f"Не найден предмет с названием: {field_name}") return field_uuid = field_uuid[0] insert_query = """ INSERT INTO field_comprehension (student_id, field, mark) VALUES (%s, %s, %s) """ cursor.execute(insert_query, (student_id, field_uuid, new_mark)) conn.commit() print("Оценка успешно добавлена!") except Exception as e: print(f"Ошибка при добавлении оценки: {e}") finally: cursor.close() def delete_grade(conn, student_id, field_name): get_field_uuid_query = """ SELECT field_id FROM field WHERE field_name = %s """ cursor = conn.cursor() try: cursor.execute(get_field_uuid_query, (field_name,)) field_uuid = cursor.fetchone() if field_uuid is None: print(f"Не найден предмет с названием: {field_name}") return field_uuid = field_uuid[0] delete_query = """ DELETE FROM field_comprehension WHERE student_id = %s AND field = %s """ cursor.execute(delete_query, (student_id, field_uuid)) conn.commit() print("Оценка успешно удалена!") except Exception as e: print(f"Ошибка при удалении оценки: {e}") finally: cursor.close() def search_grade_by_student_id(conn, student_id): get_student_grades(conn, student_id) def search_grade_by_name_group(conn, surname, name, students_group_number): query = """ SELECT S.surname, S.name, F.field_name, FC.mark FROM student S JOIN field_comprehension FC ON S.student_id = FC.student_id JOIN field F ON FC.field = F.field_id WHERE S.surname = %s AND S.name = %s AND S.students_group_number = %s """ cursor = conn.cursor() try: cursor.execute(query, (surname, name, students_group_number)) rows = cursor.fetchall() if len(rows) == 0: print("Нет данных для заданных фамилии, имени и номера группы.") else: print("Фамилия | Имя | Предмет | Оценка") print("------------------------------") for row in rows: print(" | ".join(str(v) for v in row)) except Exception as e: print(f"Ошибка: {e}") finally: cursor.close() def connect_to_database(username, password): try: conn = psycopg2.connect( host="127.0.0.1", port="5432", user=username, password=password, dbname="students" ) print("Подключено успешно!") return conn except Exception as e: print(f"Ошибка подключения: {e}") return None try: username = input("Введите логин: ") password = input("Введите пароль: ") conn = connect_to_database(username, password) if conn: cursor = conn.cursor() cursor.execute("SELECT current_user;") current_user = cursor.fetchone()[0] if current_user == "AMR admin": print("\nВыберите действие:") print("1. Просмотр своих оценок по студенческому ID") print("2. Просмотр своих оценок по фамилии, имени и номеру группы") choice = input("Введите номер действия: ") if choice == '1': student_id = input("Введите студенческий ID: ") search_grade_by_student_id(conn, student_id) elif choice == '2': surname = input("Введите фамилию: ") name = input("Введите имя: ") students_group_number = input("Введите номер группы: ") search_grade_by_name_group(conn, surname, name, students_group_number) else: print("Неверный выбор!") elif current_user == "AMR junior": print("\nВыберите действие:") print("1. Изменить оценку") print("2. Добавить оценку") print("3. Удалить оценку") print("4. Просмотр всех оценок") choice = input("Введите номер действия: ") if choice == '1': student_id = input("Введите ID студента для изменения оценки: ") field_name = input("Введите название предмета: ") new_mark = input("Введите новую оценку: ") update_grade(conn, student_id, field_name, new_mark) elif choice == '2': student_id = input("Введите ID студента для добавления оценки: ") field_name = input("Введите название предмета: ") new_mark = input("Введите новую оценку: ") add_grade(conn, student_id, field_name, new_mark) elif choice == '3': student_id = input("Введите ID студента для удаления оценки: ") field_name = input("Введите название предмета: ") delete_grade(conn, student_id, field_name) elif choice == '4': student_id = input("Введите ID студента для просмотра оценок: ") get_student_grades(conn, student_id) else: print("Неверный выбор!") else: print("Неизвестная роль пользователя.") except Exception as e: print(f"Ошибка: {e}") finally: if conn: conn.close()