scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · web...

18
Міністерство освіти і науки України Національний технічний університет України “Київський політехнічний інститут ім. Ігоря Сікорського” Факультет прикладної математики Кафедра спеціалізованих комп’ютерних систем Лабораторна робота № 3 з дисципліни «Бази даних і засоби управління» «Ознайомлення з базовими операціями СУБД PostgreSQL» Виконав: студент групи КВ-71 Янечко Андрій Сергійович

Upload: others

Post on 03-Sep-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

Міністерство освіти і науки УкраїниНаціональний технічний університет України

“Київський політехнічний інститут ім. Ігоря Сікорського”

Факультет прикладної математикиКафедра спеціалізованих комп’ютерних систем

Лабораторна робота № 3з дисципліни «Бази даних і засоби управління»

«Ознайомлення з базовими операціями СУБД PostgreSQL»

Виконав:студент групи КВ-71 Янечко Андрій Сергійович

Перевірив:___________________________________________________

Page 2: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

Завдання

Завдання роботи полягає у наступному:1.Перетворити модуль “Модель” з шаблону MVC лабораторної роботи №2

у вигляд об’єктно-реляційної проекції (ORM).2.Створити та проаналізувати різні типи індексів у PostgreSQL.3.Розробити тригер бази даних PostgreSQL.4.Навести приклади та проаналізувати рівні ізоляції транзакцій

уPostgreSQL.Порядок виконання роботи

В ході роботи розроблено:1. Логічну модель БД та Діаграму класів;2. Функціонал програмного додатку;3. ОО програмний додаток роботи з БД " … ". Для взаємодії з БД

використано ORM модуль SQLAlchemy.

Логічна модель бази даних наведена на Рисунок 1

Рисунок 1 - Логічна модель бази даних

Page 3: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

Сутнісні класи програми наведені на Рисунок 2

Рисунок 2 – Фрагмент UML діаграми сутнісних класів

Зв’язки між сутнісними класами, сгенеровані за допомогою SqlAlchemy, наведені на Рисунок 3

Рисунок 3 - Зв’язки між сутнісними класами

Примітка. Наведена вище діаграма класів не повністю відповідає стандарту. Для прикладу нижче наводиться діаграма класів додатку "Автопарк", яка побудована за допомогою додатку Enterprise Architect. Однак остаточний вигляд цієї діаграми залишається на вибір автора звіту з ЛР №3.

Page 4: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

Рисунок 4 – – Логічна модель БД "Автопарк"

а) - Зв'язуюча таблиця БД без властивостей

Page 5: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

б) - Зв'язуюча таблиця БД з властивостямиРисунок 5 – Діаграма класів-сутностей ІС "Автопарк"

Page 6: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

Меню програми наведене на Рисунок 4

Рисунок 4 - Меню програми

Навігатор по коду програми наведено нижче:1. Controller

1.1. Функція початкового меню;1.2. Функція меню таблиці;

2. Model2.1. Функція, яка повертає назви усіх таблиць в БД;2.2. Функція, яка повертає об’єкт конкретної таблиці в БД;2.3. Фнукція SELECT ALL;2.4. Функція SELECT;2.5. Функція для заповнення об’єкта з БД;2.6. Фнукція INSERT;2.7. Функція UPDATE;2.8. Функція DELETE;2.9 Функція для коміта транзакції;

3. View3.1. Функція, для отримання об’єктів від користувача;3.2. Функція, для отримування значення від користувача;

Page 7: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

3.3. Функція, для друкування головного меню;3.4 Функція, для друкування меню таблиці;

4. BaseDao4.1. Функція, для формування динамічного WHERE; 4.2. Функція, для формування динамічного UPDATE;4.3. Функція SELECT ALL;4.4. Функція SELECT;4.5. Функція DELETE;4.6. Функція UPDATE;4.7. Функція INSERT;

5. Data ba seHelper 5.1. Реалізація паттерну SINGLETONE для об’єкту який дає доступ до БД; 5.2. Функція, яка створює об’єкт типу engine ; 5.3. Функція, яка створює сесію;5.4. Функція, яка повертає інспектор;5.5. Функція, яка повертає назву всіх таблиць в БД;5.6. Фнукція, яка повертає назви колонок в таблиці;5.7. Фнукція, яка повертає список первинних ключів;5.8. Функція, яка повертає список зовнішніх ключів;5.9. Функція, яка комітить поточну сесію;

6. Utils6.1. Функція для повернення об’єкта з інпуту користувача;6.2. Функція, яка повертає значення типу Boolean для PostgreSQL;

7. Launcher8. Models

8.1. Reader;8.2. Subscription;8.3. Phone;8.4. Book;8.5. Author;8.6. Bookshelf;8.7. Archive;

9. Credentials

Page 8: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

Код програми

BaseDao.pyfrom database_helper import DatabaseHelperfrom sqlalchemy.orm.exc import NoResultFound

class BaseDao(object):

def __init__(self, model): self.database = DatabaseHelper() self.model = model

def __get_filters(self, query, columns, values): if not isinstance(columns, list) and not isinstance(values, list): # single params, such as Book.table_name, 'Kotlin Coroutines' return query.filter(columns == values) else: if isinstance(columns, list) and isinstance(values, list): # having list of params and values if columns.__len__() != values.__len__(): print("Aborting! Columns and values have different size, WTF?!") return None index = 0 for column in columns: query = query.filter(column == values[index]) index += 1 return query else: print("Aborting! Columns and values have different types, WTF?!") return None

def __get_update_query(self, query, columns, values): if not isinstance(columns, list) and not isinstance(values, list): # single params, such as Book.table_name, 'Kotlin Coroutines' return query.update({columns: values}) else: if isinstance(columns, list) and isinstance(values, list): # having list of params and values if columns.__len__() != values.__len__(): print("Aborting! Columns and values have different size, WTF?!") return None index = 0 obj = {} for column in columns: obj[column] = values[index] index += 1 query = query.update(obj) return query else: print("Aborting! Columns and values have different types, WTF?!") return None

def select_all(self): session = self.database.get_session() result = session.query(self.model).all() return result

def select(self, columns, values): session = self.database.get_session() query = session.query(self.model) return self.__get_filters(query, columns, values).all()

def delete(self, columns, values): session = self.database.get_session() result = self.select(columns, values)

Page 9: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

if result is None: print("Aborting! result is None, WTF?!")

if isinstance(result, list): # we have list of objects for obj in result: try: session.delete(obj) session.commit() print("Deleted - SUCCESSFUL") except NoResultFound: session.rollback() print("Object NOT FOUND, WTF?!")

else: # we have only one object try: session.delete(result) # session.commit() print("Deleted - SUCCESSFUL") except NoResultFound: session.rollback() print("Object NOT FOUND, WTF?!")

def update(self, columnsFind, valuesFind, columnsNew, valuesNew): session = self.database.get_session() query = session.query(self.model) query = self.__get_filters(query, columnsFind, valuesFind)

if query is None: print("Aborting! query is None, WTF?!")

query = self.__get_update_query(query, columnsNew, valuesNew)

if query is None: print("Aborting! query is None, WTF?!")

# session.commit() print("Updated - SUCCESSFUL")

def insert(self, obj): session = self.database.get_session() try: session.add(obj) # session.commit() except BaseException as exception: session.rollback() print(exception)

Controller.pyclass Controller(object):

def __init__(self, view, model): self.view = view self.model = model

def start(self): tables_names = self.model.getTablesNames() length = int(len(tables_names)) self.view.print_main_menu(tables_names) input_number = self.view.request_input() try: num = int(input_number) - 1 if num > length + 1 or num < 0: print("Wrong choice, make another...")

Page 10: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

print() self.start() else: if num == length: return self.show_table_menu(tables_names[num]) except TypeError as error: print("Wrong choice, make another...") print() self.start()

Credentials.py#private datahost = "localhost"port = "5432"database = "postgres"user = "postgres"password = ""db_name="postgres"

DatabaseHelper.pyfrom models import *import sqlalchemy as dbimport credentials as credentialsfrom sqlalchemy.orm import *from sqlalchemy import inspectfrom sqlalchemy import Boolean, BOOLEANfrom sqlalchemy.exc import NoInspectionAvailableimport utils

class DatabaseHelper(object): # params __session = None __engine = None

…Launcher.py

from database_helper import DatabaseHelperfrom controller import Controllerfrom view import Viewfrom model import Modelimport class_generator

def main(): if is_need_generate(): class_generator.generate_classes()

controller = Controller(View(), Model()) controller.start() DatabaseHelper.close()

…Model.py

from base_dao import BaseDaofrom database_helper import DatabaseHelperimport utils

Page 11: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

class Model(object):

def getTablesNames(self): return DatabaseHelper.getListOfTables()

def getTableObject(self, table_name): return DatabaseHelper.getTableObject(table_name)

…Utils.py

def map_keys_and_values_from_obect(obj): if not isinstance(obj, object): print("Aborting! U pass not objects, WTF?!") return None

columns = [] values = []

…View.py

import pandas as pd

class View(object):

def request_input(self): print("It's time to make your choice: ") return input()

Models.pyfrom sqlalchemy import Column, Integer, String, Date, Boolean, ForeignKeyfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import relationship

Base = declarative_base()

class Reader(Base): __tablename__ = "Reader"

r_id = Column("r_id", Integer, primary_key=True) r_name = Column("r_name", String) r_visit_count = Column("r_visit_count", Integer) s_id = Column("s_id", Integer, ForeignKey('Subscription.s_id'))

subscription = relationship("Subscription", backref="reader") phones = relationship("Phone", backref="reader")

def __str__(self): return "r_id={id}, r_name={name}, r_visit_count={visit_count}, s_id={subs_id}" \ "\n\tsubcription={subs}" \ "\n\tphones={phs}".format(id=self.r_id, name=self.r_name, visit_count=self.r_visit_count, subs_id={self.s_id}, subs={str(self.subscription)}, phs={str(self.phones)})

Page 12: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

ТригерТригер, який у разі якщо при додаванні запису в таблицю test_table рядка

зі значенням атрибута m_test, який містить слово test, додає до всіх інших записів ‘1’. Також, якщо це значення не містить слово test, то такий запис не вставляється в таблицю.

Page 13: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

Тригер:

Дослідження рівнів ізоляціїДослід проводився з двома паралельними запитами UPDATE на один і

той самий об’єкт (запис):

1. READ COMMITTED

Page 14: scs.kpi.uascs.kpi.ua/sites/default/files/pryklad._yanechko_andriy_… · Web viewЛабораторна робота 3 з дисципліни «Бази даних і засоби

Клієнт, який почав операцію UPDATE пізніше чекав, поки інший клієнт закомітить транзакцію.

2. SEREALIZABLE та REPEATABLE READ