Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
7 сем / курсач / мисприс_1374_отчет_по_курсовой_Наволоцкий_Зырянов_Харитонов.docx
Скачиваний:
5
Добавлен:
29.03.2025
Размер:
2.22 Mб
Скачать

3.2. Fill Example Data - заполнение базы данных тестовыми данными

Для заполнения базы данных тестовыми данными требуется нажать кнопку “Fill Example Data”. Если база данных пуста, увидим окно об успешном заполнении базы тестовым примером

Сама база данных теперь

Кроме того, для предотвращения заполнения базы данных с пользовательскими даными тестовыми данными для этого предусмотрено ограничение, которое не позволяет в непустую базу данных вставить тестовые данные. Вот как это будет выглядеть при непустой базе данных, если мы нажмем кнопку “Fill Example Data”

Листинг кода

Так как большинство функций было разработано в лабораторной работе, на основе которой написана эта курсовая работа, то приведем код только интерфейсной части, опустив содержание функций, так же не приводя код предыдущей курсовой работы, на которой строится эта.

import tkinter as tk

from tkinter import *

from tkinter import ttk

import sqlite3

from tkinter import messagebox

path = "C:/Users/admin/source/repos/UNIVERSITY_repos/4 course/7 sem/mispris/coursework-2/furniture.db"

class DatabaseApp:

def __init__(self, root):

self.root = root

self.root.title("coursework")

root.geometry("1000x600")

self.conn = sqlite3.connect(path)

self.cursor = self.conn.cursor()

self.tree = ttk.Treeview(root, show="headings")

self.tree.grid(row=0, column=0, columnspan=6, sticky="nsew", padx=6, pady=10)

self.load_button = ttk.Button(root, text="Load Products", command=self.load_products)

self.load_button.grid(row=1, column=0, sticky="ew", padx=6, pady=2)

self.add_product_button = ttk.Button(root, text="Add product", command=self.add_product)

self.add_product_button.grid(row=2, column=0, sticky="ew", padx=6, pady=2)

self.edit_button = ttk.Button(root, text="Edit Selected", command=self.edit_product)

self.edit_button.grid(row=3, column=0, sticky="ew", padx=6, pady=2)

self.delete_button = ttk.Button(root, text="Delete Selected", command=self.delete_product)

self.delete_button.grid(row=4, column=0, sticky="ew", padx=6, pady=2)

self.load_find_components_by_objectbutton = ttk.Button(root, text="find components by object ", command=self.load_find_components_by_object)

self.load_find_components_by_objectbutton.grid(row=5, column=0, sticky="ew", padx=6, pady=2)

self.find_components_recursive_object_button = ttk.Button(root, text="find components recursive", command=self.find_components_recursive)

self.find_components_recursive_object_button.grid(row=6, column=0, sticky="ew", padx=6, pady=2)

self.load_existing_acceptable_components_by_object_button = ttk.Button(root, text="available components category", command=self.load_existing_acceptable_components_by_object)

self.load_existing_acceptable_components_by_object_button.grid(row=7, column=0, sticky="ew", padx=6, pady=2)

self.load_existing_acceptable_components_by_object_recursive_button = ttk.Button(root, text="available components recursive category", command=self.load_existing_acceptable_components_by_object_recursive)

self.load_existing_acceptable_components_by_object_recursive_button.grid(row=8, column=0, sticky="ew", padx=6, pady=2)

self.load_category_button = ttk.Button(root, text="Load Categories", command=self.load_categories)

self.load_category_button.grid(row=1, column=1, sticky="ew", padx=6, pady=2)

self.add_category_button = ttk.Button(root, text="Add Category", command=self.add_category)

self.add_category_button.grid(row=2, column=1, sticky="ew", padx=6, pady=2)

self.edit_category_button = ttk.Button(root, text="Edit Category", command=self.edit_category)

self.edit_category_button.grid(row=3, column=1, sticky="ew", padx=6, pady=2)

self.delete_category_button = ttk.Button(root, text="Delete Category", command=self.delete_category)

self.delete_category_button.grid(row=4, column=1, sticky="ew", padx=6, pady=2)

self.show_parents_button = ttk.Button(root, text="Show Parents", command=self.show_category_parents)

self.show_parents_button.grid(row=5, column=1, sticky="ew", padx=6, pady=2)

self.show_children_button = ttk.Button(root, text="Show Children", command=self.show_category_children)

self.show_children_button.grid(row=6, column=1, sticky="ew", padx=6, pady=2)

self.show_products_button = ttk.Button(root, text="Show products", command=self.show_products_for_category)

self.show_products_button.grid(row=7, column=1, sticky="ew", padx=6, pady=2)

self.load_acceptable_components_by_class_button = ttk.Button(root, text="Show acceptable components by class", command=self.load_acceptable_components_by_class)

self.load_acceptable_components_by_class_button.grid(row=8, column=1, sticky="ew", padx=6, pady=2)

self.load_acceptable_components_by_class_recursive_button = ttk.Button(root, text="Show acceptable components by class recoursive", command=self.load_acceptable_components_by_class_recursive)

self.load_acceptable_components_by_class_recursive_button.grid(row=9, column=1, sticky="ew", padx=6, pady=2)

self.load_unit_button = ttk.Button(root, text="Load Unit", command=self.load_unit)

self.load_unit_button.grid(row=1, column=2, sticky="ew", padx=6, pady=2)

self.add_unit_button = ttk.Button(root, text="Add Unit", command=self.add_unit)

self.add_unit_button.grid(row=2, column=2, sticky="ew", padx=6, pady=2)

self.edit_unit_button = ttk.Button(root, text="Edit Selected", command=self.edit_unit)

self.edit_unit_button.grid(row=3, column=2, sticky="ew", padx=6, pady=2)

self.delete_unit_button = ttk.Button(root, text="Delete Selected", command=self.delete_unit)

self.delete_unit_button.grid(row=4, column=2, sticky="ew", padx=6, pady=2)

self.load_acceptable_components_button = ttk.Button(root, text="Load acceptable components", command=self.load_acceptable_component)

self.load_acceptable_components_button.grid(row=1, column=3, sticky="ew", padx=6, pady=2)

self.create_acceptable_component_button = ttk.Button(root, text="create acceptable component", command=self.create_acceptable_component)

self.create_acceptable_component_button.grid(row=2, column=3, sticky="ew", padx=6, pady=2)

self.inherit_acceptable_components_button = ttk.Button(root, text="inherit acceptable components", command=self.inherit_acceptable_components)

self.inherit_acceptable_components_button.grid(row=3, column=3, sticky="ew", padx=6, pady=2)

self.delete_acceptable_component_button = ttk.Button(root, text="Delete acceptable components", command=self.delete_acceptable_component)

self.delete_acceptable_component_button.grid(row=4, column=3, sticky="ew", padx=6, pady=2)

self.load_prod_position_union_button = ttk.Button(root, text="Load prod position union", command=self.load_prod_position_union)

self.load_prod_position_union_button.grid(row=1, column=4, sticky="ew", padx=6, pady=2)

self.create_prod_position_union_button = ttk.Button(root, text="create prod position union", command=self.create_prod_position_union)

self.create_prod_position_union_button.grid(row=2, column=4, sticky="ew", padx=6, pady=2)

self.delete_prod_position_union_button = ttk.Button(root, text="Delete prod position row", command=self.delete_prod_position_union)

self.delete_prod_position_union_button.grid(row=3, column=4, sticky="ew", padx=6, pady=2)

self.edit_prod_position_union_quantity_button = ttk.Button(root, text="New quantity prod position", command=self.edit_prod_position_union_quantity)

self.edit_prod_position_union_quantity_button.grid(row=4, column=4, sticky="ew", padx=6, pady=2)

self.fill_example_data_button = ttk.Button(self.root, text="Fill Example Data", command=self.fill_example_data)

self.fill_example_data_button.grid(row=1, column=5, sticky="ew", padx=6, pady=2)

self.delete_all_data_button = ttk.Button(self.root, text="Delete All Data", command=self.delete_all_data)

self.delete_all_data_button.grid(row=2, column=5, sticky="ew", padx=6, pady=2)

# Configure row and column to resize

root.rowconfigure(0, weight=1)

root.columnconfigure(0, weight=1)

root.columnconfigure(1, weight=1)

root.columnconfigure(2, weight=1)

root.columnconfigure(3, weight=1)

root.columnconfigure(4, weight=1)

root.columnconfigure(5, weight=1)

def create_category_table():

self.cursor.execute('''CREATE TABLE IF NOT EXISTS category

(id INTEGER PRIMARY KEY AUTOINCREMENT,

id_parent INTEGER CHECK (id_parent != id),

category_name TEXT UNIQUE,

id_unit INTEGER,

FOREIGN KEY (id_parent) REFERENCES category(id))''')

self.conn.commit()

def create_product_table():

self.cursor.execute('''CREATE TABLE IF NOT EXISTS product

(id INTEGER PRIMARY KEY AUTOINCREMENT,

id_category INTEGER,

id_unit INTEGER,

product_name TEXT NOT NULL,

quantity INTEGER DEFAULT 0,

price REAL DEFAULT 0,

FOREIGN KEY (id_unit) REFERENCES unit(id),

FOREIGN KEY (id_category) REFERENCES category(id))''')

self.conn.commit()

def create_unit_table():

self.cursor.execute('''CREATE TABLE IF NOT EXISTS unit

(id INTEGER PRIMARY KEY AUTOINCREMENT,

unit_name TEXT NOT NULL UNIQUE,

unit_name_short TEXT NOT NULL)''')

self.conn.commit()

def create_acceptable_components_table():

self.cursor.execute('''

CREATE TABLE IF NOT EXISTS acceptable_components (

id INTEGER PRIMARY KEY AUTOINCREMENT,

class_id INTEGER NOT NULL,

component_id INTEGER NOT NULL,

UNIQUE(class_id, component_id),

FOREIGN KEY (class_id) REFERENCES category(id) ON DELETE CASCADE,

FOREIGN KEY (component_id) REFERENCES category(id) ON DELETE CASCADE

)

''')

self.conn.commit()

def create_prod_position_union_table():

self.cursor.execute('''

CREATE TABLE IF NOT EXISTS prod_position_union (

id INTEGER PRIMARY KEY AUTOINCREMENT,

prod_id INTEGER NOT NULL,

comp_id INTEGER NOT NULL,

quantity INTEGER NOT NULL CHECK (quantity > 0),

UNIQUE(prod_id, comp_id),

FOREIGN KEY (prod_id) REFERENCES product(id) ON DELETE CASCADE,

FOREIGN KEY (comp_id) REFERENCES product(id) ON DELETE CASCADE

)

''')

self.conn.commit()

def creating_tables():

create_category_table()

create_product_table()

create_unit_table()

# coursework-2

create_acceptable_components_table()

create_prod_position_union_table()

creating_tables()

def load_acceptable_component(self):

for row in self.tree.get_children():

self.tree.delete(row)

self.cursor.execute("SELECT * FROM acceptable_components")

rows = self.cursor.fetchall()

column_names = [description[0] for description in self.cursor.description]

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=100) # Устанавливаем ширину столбцов

for row in rows:

self.tree.insert("", END, values=row)

# new_class_id, new_component_id

def create_acceptable_component(self):

add_window = Toplevel(self.root)

add_window.title("Add acceptable component")

Label(add_window, text="Component name").grid(row=0, column=0)

component_name_entry = Entry(add_window)

component_name_entry.grid(row=0, column=1)

Label(add_window, text="Class name").grid(row=1, column=0)

class_name_entry = Entry(add_window)

class_name_entry.grid(row=1, column=1)

def save_new_component():

class_name = class_name_entry.get()

component_name = component_name_entry.get()

self.cursor.execute("SELECT id FROM category WHERE category_name = ?", (class_name,))

new_class_id = self.cursor.fetchone()

if new_class_id:

new_class_id = new_class_id[0]

else:

messagebox.showerror("Error", f"Class name with id - '{new_class_id}' not found.")

return

self.cursor.execute("SELECT id FROM category WHERE category_name = ?", (component_name,))

new_component_id = self.cursor.fetchone()

if new_component_id:

new_component_id = new_component_id[0]

else:

messagebox.showerror("Error", f"Component name with id - '{new_component_id}' not found.")

return

if new_class_id == new_component_id:

messagebox.showerror("Error: нельзя создать цикл с одинаковыми class_id и component_id!")

return

try:

# Recursive query to check for cycles in acceptable_components

self.cursor.execute('''

WITH RECURSIVE cycle_check(class_id, comp_id) AS (

SELECT class_id, component_id

FROM acceptable_components

WHERE class_id = ?

UNION ALL

SELECT ac.class_id, ac.component_id

FROM acceptable_components ac

INNER JOIN cycle_check cc ON ac.class_id = cc.comp_id

)

SELECT 1 FROM cycle_check WHERE comp_id = ?

''', (new_component_id, new_class_id))

# If a result exists, it means adding the new entry would create a cycle

if self.cursor.fetchone():

print(f"Error: добавление пары ({new_class_id}, {new_component_id}) создаёт цикл!")

return 0 # Failure

# Insert the new relationship if no cycle is detected

self.cursor.execute('''

INSERT INTO acceptable_components (class_id, component_id)

VALUES (?, ?)

''', (new_class_id, new_component_id))

self.conn.commit()

self.load_acceptable_component()

add_window.destroy()

print(f"Компонент успешно добавлен: class_id={new_class_id}, component_id={new_component_id}")

return 1 # Success

except sqlite3.OperationalError as e:

print(f"SQL Error: {e}")

return 0 # Failure

except sqlite3.IntegrityError:

print("Error: нарушение ограничений UNIQUE или FOREIGN KEY.")

return 0 # Failure

Button(add_window, text="Save", command=save_new_component).grid(row=5, column=0, columnspan=2)

# cl_id - для какого класса наследуемся

def inherit_acceptable_components(self):

add_window = Toplevel(self.root)

add_window.title("Inherit acceptable components")

Label(add_window, text="Class name").grid(row=0, column=0)

class_name_entry = Entry(add_window)

class_name_entry.grid(row=0, column=1)

def save_new_inherit_acceptable_components():

class_name = class_name_entry.get()

self.cursor.execute("SELECT id FROM category WHERE category_name = ?", (class_name,))

cl_id = self.cursor.fetchone()

if cl_id:

cl_id = cl_id[0]

else:

messagebox.showerror("Error", f"Category name with id - '{cl_id}' not found.")

return

inserted_count = 0

try:

self.cursor.execute('SELECT id_parent FROM category WHERE id = ?', (cl_id,))

parent_cl_id = self.cursor.fetchone()

if parent_cl_id is None:

messagebox.showerror("Parent class ID not found")

return

self.cursor.execute('''

SELECT component_id FROM acceptable_components

WHERE class_id = ?

''', (parent_cl_id[0],))

components = self.cursor.fetchall()

# Insert acceptable components for the child class

for (component_id,) in components:

self.cursor.execute('''

INSERT OR IGNORE INTO acceptable_components (class_id, component_id)

VALUES (?, ?)

''', (cl_id, component_id))

inserted_count += self.cursor.rowcount

self.conn.commit()

messagebox.showinfo("Success", f"произведено {inserted_count} наследований.")

add_window.destroy()

print(f'произведено {inserted_count} наследований')

except Exception as e:

print(f"Error: {e}")

return inserted_count

Button(add_window, text="Save", command=save_new_inherit_acceptable_components).grid(row=5, column=0, columnspan=2)

def load_prod_position_union(self):

for row in self.tree.get_children():

self.tree.delete(row)

self.cursor.execute("SELECT * FROM prod_position_union")

rows = self.cursor.fetchall()

column_names = [description[0] for description in self.cursor.description]

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=100) # Устанавливаем ширину столбцов

for row in rows:

self.tree.insert("", END, values=row)

# new_object_id, new_component_id, new_quantity

def create_prod_position_union(self):

add_window = Toplevel(self.root)

add_window.title("Add prod position union")

Label(add_window, text="Product name").grid(row=0, column=0)

product_name_entry = Entry(add_window)

product_name_entry.grid(row=0, column=1)

Label(add_window, text="Component product name").grid(row=1, column=0)

component_name_entry = Entry(add_window)

component_name_entry.grid(row=1, column=1)

Label(add_window, text="Quantity").grid(row=2, column=0)

quantity_entry = Entry(add_window)

quantity_entry.grid(row=2, column=1)

def save_new_prod_position_union():

product_name = product_name_entry.get()

component_name = component_name_entry.get()

quantity_str = quantity_entry.get()

try:

quantity = int(quantity_str)

except ValueError:

messagebox.showerror("Error", "Quantity must be a valid integer.")

return

if (quantity <= 0):

messagebox.showerror("Error", f"quantity cant be <= 0.")

return

self.cursor.execute("SELECT id FROM product WHERE product_name = ?", (product_name,))

new_object_id = self.cursor.fetchone()

if new_object_id:

new_object_id = new_object_id[0]

else:

messagebox.showerror("Error", f"Product name with id - '{new_object_id}' not found.")

return

self.cursor.execute("SELECT id FROM product WHERE product_name = ?", (component_name,))

new_component_id = self.cursor.fetchone()

if new_component_id:

new_component_id = new_component_id[0]

else:

messagebox.showerror("Error", f"Component with id - '{new_component_id}' not found.")

return

try:

self.cursor.execute('SELECT id_category FROM product WHERE id = ?', (new_object_id,))

obj_class_id = self.cursor.fetchone()

if obj_class_id is None:

messagebox.showerror("Object ID not found")

return

self.cursor.execute('SELECT id_category FROM product WHERE id = ?', (new_component_id,))

comp_class_id = self.cursor.fetchone()

if comp_class_id is None:

messagebox.showerror("Component ID not found")

return

self.cursor.execute('''

SELECT 1

FROM acceptable_components

WHERE class_id = ? AND component_id = ?

''', (obj_class_id[0], comp_class_id[0]))

if self.cursor.fetchone() is None:

messagebox.showerror("Invalid composition for the object!")

return

self.cursor.execute('''

INSERT INTO prod_position_union (prod_id, comp_id, quantity)

VALUES (?, ?, ?)

''', (new_object_id, new_component_id, quantity))

self.conn.commit()

self.load_prod_position_union()

add_window.destroy()

print('таблица prod_position_union успешно обновлена новым значением.')

return 1 # Success

except Exception as e:

print(f"Error: {e}")

return 0 # Failure

Button(add_window, text="Save", command=save_new_prod_position_union).grid(row=5, column=0, columnspan=2)

def delete_prod_position_union(self):

try:

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

prod_position_union_id = selected_product[0]

self.cursor.execute("DELETE FROM prod_position_union WHERE id = ?", (prod_position_union_id,))

self.conn.commit()

self.load_prod_position_union()

except IndexError:

pass

def delete_acceptable_component(self):

try:

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

acceptable_component_id = selected_product[0]

self.cursor.execute("DELETE FROM acceptable_components WHERE id = ?", (acceptable_component_id,))

self.conn.commit()

self.load_acceptable_component()

except IndexError:

pass

def edit_prod_position_union_quantity(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

prod_position_union_id = selected_product[0]

add_window = Toplevel(self.root)

add_window.title("Enter new quantity")

Label(add_window, text="Product name").grid(row=0, column=0)

quantity_entry = Entry(add_window)

quantity_entry.grid(row=0, column=1)

def save_quantity():

quantity_str = quantity_entry.get()

try:

quantity = int(quantity_str)

except ValueError:

messagebox.showerror("Error", "Quantity must be a valid integer.")

return

if (quantity <= 0):

messagebox.showerror("Error", f"quantity cant be <= 0.")

return

try:

self.cursor.execute('''

UPDATE prod_position_union

SET quantity = ?

WHERE id = ?

''', (quantity, prod_position_union_id))

self.conn.commit()

self.load_prod_position_union()

add_window.destroy()

except IndexError:

pass

Button(add_window, text="Save", command=save_quantity).grid(row=5, column=0, columnspan=2)

def load_acceptable_components_by_class(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

class_id = selected_product[0]

# Clear the treeview

for row in self.tree.get_children():

self.tree.delete(row)

# Fetch component IDs

self.cursor.execute("SELECT component_id FROM acceptable_components WHERE class_id = ?", (class_id,))

component_ids = self.cursor.fetchall()

if not component_ids:

print(f"No components found for class_id {class_id}.")

return

# Fetch component names for each ID

result = []

for component_id in component_ids:

print(f'component_id - {component_id}')

self.cursor.execute("SELECT category_name FROM category WHERE id = ?", (component_id[0],))

name = self.cursor.fetchone()

if name:

print(f'component_id[0], name[0] - {component_id[0], name[0]}')

result.append((component_id[0], name[0]))

print(f'Для класса с id = {class_id}, составные части: {result}')

for res in result:

print(f'res = {res}')

# Explicitly set up the columns

self.tree["columns"] = ("component_id", "category_name")

self.tree.heading("#0", text="", anchor="w") # Clear default column

self.tree.column("#0", width=0, stretch=False) # Hide the first empty column

for col in self.tree["columns"]:

self.tree.heading(col, text=col, anchor="w")

self.tree.column(col, anchor="w", width=150) # Set width for each column

# self.tree.insert("", "end", values=result)

# Insert rows into the treeview

for row in result:

self.tree.insert("", "end", values=(row[0], row[1]))

# self.tree.insert("", END, values=row)

def load_find_components_by_object(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

object_id = selected_product[0]

for row in self.tree.get_children():

self.tree.delete(row)

self.cursor.execute("SELECT comp_id, quantity FROM prod_position_union WHERE prod_id = ?", (object_id,))

components = self.cursor.fetchall()

if not components:

return []

result = []

for comp_id, quantity in components:

self.cursor.execute("SELECT product_name, quantity FROM product WHERE id = ?", (comp_id,))

name = self.cursor.fetchone()

if name:

result.append(( [name[0]], [ quantity]))

print(f'для объекта с id = {object_id}, составные части: {result}')

column_names = [description[0] for description in self.cursor.description]

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=100) # Устанавливаем ширину столбцов

for row in result:

self.tree.insert("", END, values=row)

def load_acceptable_components_by_class_recursive(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

class_id = selected_product[0]

for row in self.tree.get_children():

self.tree.delete(row)

def find_components(class_id, result):

self.cursor.execute("SELECT component_id FROM acceptable_components WHERE class_id = ?", (class_id,))

components = self.cursor.fetchall()

for component in components:

component_id = component[0]

result.add(component_id)

find_components(component_id, result)

result = set()

find_components(class_id, result)

# Fetch component names for the result set

component_names = []

for component_id in result:

self.cursor.execute("SELECT category_name FROM category WHERE id = ?", (component_id,))

component_name = self.cursor.fetchone()

if component_name:

component_names.append((component_name[0], component_id))

print(f'результат подходящих компонент для id {class_id} - ({component_names})')

column_names = [description[0] for description in self.cursor.description]

print(f'column_names - - - -{column_names}')

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=120) # Устанавливаем ширину столбцов

for row in component_names:

self.tree.insert("", END, values=row)

# object_id

def find_components_recursive(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

object_id = selected_product[0]

for row in self.tree.get_children():

self.tree.delete(row)

# Recursive function to find components

def find_components(obj_id, result):

self.cursor.execute("SELECT comp_id, quantity FROM prod_position_union WHERE prod_id = ?", (obj_id,))

components = self.cursor.fetchall()

for comp_id, quantity in components:

result[comp_id] = result.get(comp_id, 0) + quantity

find_components(comp_id, result)

result = {}

find_components(object_id, result)

# Fetch component names for the result

final_result = []

for comp_id, total_quantity in result.items():

self.cursor.execute("SELECT product_name FROM product WHERE id = ?", (comp_id,))

name = self.cursor.fetchone()

if name:

final_result.append((name[0], comp_id, total_quantity))

print(f'для объекта с id = {object_id} компоненты, найденные рекурсивно: {final_result}')

column_names = [description[0] for description in self.cursor.description]

print(f'column_names - - - -{column_names}')

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=120) # Устанавливаем ширину столбцов

for row in final_result:

self.tree.insert("", END, values=row)

def load_existing_acceptable_components_by_object(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

object_id = selected_product[0]

for row in self.tree.get_children():

self.tree.delete(row)

self.cursor.execute("SELECT id_category FROM product WHERE id = ?", (object_id,))

id_category = self.cursor.fetchone()[0]

# Find the class_id of the object

self.cursor.execute("SELECT id_parent FROM category WHERE id = ?", (id_category,))

class_info = self.cursor.fetchone()

if not class_info:

return []

class_id = class_info[0]

self.cursor.execute('''

SELECT component_id FROM acceptable_components WHERE class_id = ?

''', (class_id,))

components = self.cursor.fetchall()

# Fetch component names for the result

result = []

for component in components:

component_id = component[0]

self.cursor.execute("SELECT category_name FROM category WHERE id = ?", (component_id,))

name = self.cursor.fetchone()

if name:

# result.append((component_id, name[0]))

result.append((name[0]))

print(f'result - {result}')

column_names = [description[0] for description in self.cursor.description]

print(f'column_names - - - -{column_names}')

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=120) # Устанавливаем ширину столбцов

for row in result:

self.tree.insert("", END, values=row)

def load_existing_acceptable_components_by_object_recursive(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

obj_id = selected_product[0]

self.cursor.execute("SELECT id_category FROM product WHERE id = ?", (obj_id,))

class_id = self.cursor.fetchone()

if not class_id:

return []

class_id = class_id[0]

for row in self.tree.get_children():

self.tree.delete(row)

def find_acceptable_components_by_class_recursive(class_id):

try:

def find_components(class_id, result):

self.cursor.execute("SELECT component_id FROM acceptable_components WHERE class_id = ?", (class_id,))

components = self.cursor.fetchall()

for component in components:

component_id = component[0]

result.add(component_id)

find_components(component_id, result)

result = set()

find_components(class_id, result)

# Fetch component names for the result set

component_names = []

for component_id in result:

self.cursor.execute("SELECT category_name FROM category WHERE id = ?", (component_id,))

component_name = self.cursor.fetchone()

if component_name:

component_names.append((component_id, component_name[0]))

print(f'результат подходящих компонент для id {class_id} - ({component_names})')

return component_names

except Exception as e:

print(f"Error occurred while finding acceptable components: {e}")

return []

def find_components(cl_id):

components = []

acceptable_components = find_acceptable_components_by_class_recursive(cl_id)

for component in acceptable_components:

component_id = component[0]

self.cursor.execute("SELECT id, product_name FROM product WHERE id_category = ?", (component_id,))

obj_data = self.cursor.fetchone()

if obj_data:

# components.append({

# obj_data[1]

# })

components.append({

'component_name': obj_data[1],

'component_id': obj_data[0]

})

return components

components = find_components(class_id)

column_names = [description[0] for description in self.cursor.description]

print(f'column_names - - - -{column_names}')

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=120)

for row in components:

self.tree.insert("", END, values=(row['component_id'], row['component_name']))

def __del__(self):

self.conn.close()

class DatabaseUserApp:

def __init__(self, root):

self.root = root

self.root.title("coursework")

root.geometry("1000x600")

self.conn = sqlite3.connect(path)

self.cursor = self.conn.cursor()

self.tree = ttk.Treeview(root, show="headings")

self.tree.grid(row=0, column=0, columnspan=5, sticky="nsew", padx=6, pady=10)

self.load_button = ttk.Button(root, text="Load Products", command=self.load_products)

self.load_button.grid(row=1, column=0, sticky="ew", padx=6, pady=2)

self.load_find_components_by_objectbutton = ttk.Button(root, text="find components by object ", command=self.load_find_components_by_object)

self.load_find_components_by_objectbutton.grid(row=5, column=0, sticky="ew", padx=6, pady=2)

self.find_components_recursive_object_button = ttk.Button(root, text="find components recursive", command=self.find_components_recursive)

self.find_components_recursive_object_button.grid(row=6, column=0, sticky="ew", padx=6, pady=2)

self.load_existing_acceptable_components_by_object_button = ttk.Button(root, text="available components category", command=self.load_existing_acceptable_components_by_object)

self.load_existing_acceptable_components_by_object_button.grid(row=7, column=0, sticky="ew", padx=6, pady=2)

self.load_existing_acceptable_components_by_object_recursive_button = ttk.Button(root, text="available components recursive category", command=self.load_existing_acceptable_components_by_object_recursive)

self.load_existing_acceptable_components_by_object_recursive_button.grid(row=8, column=0, sticky="ew", padx=6, pady=2)

self.load_category_button = ttk.Button(root, text="Load Categories", command=self.load_categories)

self.load_category_button.grid(row=1, column=1, sticky="ew", padx=6, pady=2)

self.show_parents_button = ttk.Button(root, text="Show Parents", command=self.show_category_parents)

self.show_parents_button.grid(row=5, column=1, sticky="ew", padx=6, pady=2)

self.show_children_button = ttk.Button(root, text="Show Children", command=self.show_category_children)

self.show_children_button.grid(row=6, column=1, sticky="ew", padx=6, pady=2)

self.show_products_button = ttk.Button(root, text="Show products", command=self.show_products_for_category)

self.show_products_button.grid(row=7, column=1, sticky="ew", padx=6, pady=2)

self.load_acceptable_components_by_class_button = ttk.Button(root, text="Show acceptable components by class", command=self.load_acceptable_components_by_class)

self.load_acceptable_components_by_class_button.grid(row=8, column=1, sticky="ew", padx=6, pady=2)

self.load_acceptable_components_by_class_recursive_button = ttk.Button(root, text="Show acceptable components by class recoursive", command=self.load_acceptable_components_by_class_recursive)

self.load_acceptable_components_by_class_recursive_button.grid(row=9, column=1, sticky="ew", padx=6, pady=2)

self.load_unit_button = ttk.Button(root, text="Load Unit", command=self.load_unit)

self.load_unit_button.grid(row=1, column=2, sticky="ew", padx=6, pady=2)

self.load_acceptable_components_button = ttk.Button(root, text="Load acceptable components", command=self.load_acceptable_component)

self.load_acceptable_components_button.grid(row=1, column=3, sticky="ew", padx=6, pady=2)

self.load_prod_position_union_button = ttk.Button(root, text="Load prod position union", command=self.load_prod_position_union)

self.load_prod_position_union_button.grid(row=1, column=4, sticky="ew", padx=6, pady=2)

# Configure row and column to resize

root.rowconfigure(0, weight=1)

root.columnconfigure(0, weight=1)

root.columnconfigure(1, weight=1)

root.columnconfigure(2, weight=1)

root.columnconfigure(3, weight=1)

root.columnconfigure(4, weight=1)

def create_category_table():

self.cursor.execute('''CREATE TABLE IF NOT EXISTS category

(id INTEGER PRIMARY KEY AUTOINCREMENT,

id_parent INTEGER CHECK (id_parent != id),

category_name TEXT UNIQUE,

id_unit INTEGER,

FOREIGN KEY (id_parent) REFERENCES category(id))''')

self.conn.commit()

def create_product_table():

self.cursor.execute('''CREATE TABLE IF NOT EXISTS product

(id INTEGER PRIMARY KEY AUTOINCREMENT,

id_category INTEGER,

id_unit INTEGER,

product_name TEXT NOT NULL,

quantity INTEGER DEFAULT 0,

price REAL DEFAULT 0,

FOREIGN KEY (id_unit) REFERENCES unit(id),

FOREIGN KEY (id_category) REFERENCES category(id))''')

self.conn.commit()

def create_unit_table():

self.cursor.execute('''CREATE TABLE IF NOT EXISTS unit

(id INTEGER PRIMARY KEY AUTOINCREMENT,

unit_name TEXT NOT NULL UNIQUE,

unit_name_short TEXT NOT NULL)''')

self.conn.commit()

def create_acceptable_components_table():

self.cursor.execute('''

CREATE TABLE IF NOT EXISTS acceptable_components (

id INTEGER PRIMARY KEY AUTOINCREMENT,

class_id INTEGER NOT NULL,

component_id INTEGER NOT NULL,

UNIQUE(class_id, component_id),

FOREIGN KEY (class_id) REFERENCES category(id) ON DELETE CASCADE,

FOREIGN KEY (component_id) REFERENCES category(id) ON DELETE CASCADE

)

''')

self.conn.commit()

def create_prod_position_union_table():

self.cursor.execute('''

CREATE TABLE IF NOT EXISTS prod_position_union (

id INTEGER PRIMARY KEY AUTOINCREMENT,

prod_id INTEGER NOT NULL,

comp_id INTEGER NOT NULL,

quantity INTEGER NOT NULL CHECK (quantity > 0),

UNIQUE(prod_id, comp_id),

FOREIGN KEY (prod_id) REFERENCES product(id) ON DELETE CASCADE,

FOREIGN KEY (comp_id) REFERENCES product(id) ON DELETE CASCADE

)

''')

self.conn.commit()

def creating_tables():

create_category_table()

create_product_table()

create_unit_table()

# coursework-2

create_acceptable_components_table()

create_prod_position_union_table()

creating_tables()

def load_acceptable_component(self):

for row in self.tree.get_children():

self.tree.delete(row)

self.cursor.execute("SELECT * FROM acceptable_components")

rows = self.cursor.fetchall()

column_names = [description[0] for description in self.cursor.description]

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=100) # Устанавливаем ширину столбцов

for row in rows:

self.tree.insert("", END, values=row)

# new_class_id, new_component_id

def create_acceptable_component(self):

add_window = Toplevel(self.root)

add_window.title("Add acceptable component")

Label(add_window, text="Component name").grid(row=0, column=0)

component_name_entry = Entry(add_window)

component_name_entry.grid(row=0, column=1)

Label(add_window, text="Class name").grid(row=1, column=0)

class_name_entry = Entry(add_window)

class_name_entry.grid(row=1, column=1)

def save_new_component():

class_name = class_name_entry.get()

component_name = component_name_entry.get()

self.cursor.execute("SELECT id FROM category WHERE category_name = ?", (class_name,))

new_class_id = self.cursor.fetchone()

if new_class_id:

new_class_id = new_class_id[0]

else:

messagebox.showerror("Error", f"Class name with id - '{new_class_id}' not found.")

return

self.cursor.execute("SELECT id FROM category WHERE category_name = ?", (component_name,))

new_component_id = self.cursor.fetchone()

if new_component_id:

new_component_id = new_component_id[0]

else:

messagebox.showerror("Error", f"Component name with id - '{new_component_id}' not found.")

return

if new_class_id == new_component_id:

messagebox.showerror("Error: нельзя создать цикл с одинаковыми class_id и component_id!")

return

try:

# Recursive query to check for cycles in acceptable_components

self.cursor.execute('''

WITH RECURSIVE cycle_check(class_id, comp_id) AS (

SELECT class_id, component_id

FROM acceptable_components

WHERE class_id = ?

UNION ALL

SELECT ac.class_id, ac.component_id

FROM acceptable_components ac

INNER JOIN cycle_check cc ON ac.class_id = cc.comp_id

)

SELECT 1 FROM cycle_check WHERE comp_id = ?

''', (new_component_id, new_class_id))

# If a result exists, it means adding the new entry would create a cycle

if self.cursor.fetchone():

print(f"Error: добавление пары ({new_class_id}, {new_component_id}) создаёт цикл!")

return 0 # Failure

# Insert the new relationship if no cycle is detected

self.cursor.execute('''

INSERT INTO acceptable_components (class_id, component_id)

VALUES (?, ?)

''', (new_class_id, new_component_id))

self.conn.commit()

self.load_acceptable_component()

add_window.destroy()

print(f"Компонент успешно добавлен: class_id={new_class_id}, component_id={new_component_id}")

return 1 # Success

except sqlite3.OperationalError as e:

print(f"SQL Error: {e}")

return 0 # Failure

except sqlite3.IntegrityError:

print("Error: нарушение ограничений UNIQUE или FOREIGN KEY.")

return 0 # Failure

Button(add_window, text="Save", command=save_new_component).grid(row=5, column=0, columnspan=2)

# cl_id - для какого класса наследуемся

def inherit_acceptable_components(self):

add_window = Toplevel(self.root)

add_window.title("Inherit acceptable components")

Label(add_window, text="Class name").grid(row=0, column=0)

class_name_entry = Entry(add_window)

class_name_entry.grid(row=0, column=1)

def save_new_inherit_acceptable_components():

class_name = class_name_entry.get()

self.cursor.execute("SELECT id FROM category WHERE category_name = ?", (class_name,))

cl_id = self.cursor.fetchone()

if cl_id:

cl_id = cl_id[0]

else:

messagebox.showerror("Error", f"Category name with id - '{cl_id}' not found.")

return

inserted_count = 0

try:

self.cursor.execute('SELECT id_parent FROM category WHERE id = ?', (cl_id,))

parent_cl_id = self.cursor.fetchone()

if parent_cl_id is None:

messagebox.showerror("Parent class ID not found")

return

self.cursor.execute('''

SELECT component_id FROM acceptable_components

WHERE class_id = ?

''', (parent_cl_id[0],))

components = self.cursor.fetchall()

# Insert acceptable components for the child class

for (component_id,) in components:

self.cursor.execute('''

INSERT OR IGNORE INTO acceptable_components (class_id, component_id)

VALUES (?, ?)

''', (cl_id, component_id))

inserted_count += self.cursor.rowcount

self.conn.commit()

messagebox.showinfo("Success", f"произведено {inserted_count} наследований.")

add_window.destroy()

print(f'произведено {inserted_count} наследований')

except Exception as e:

print(f"Error: {e}")

return inserted_count

Button(add_window, text="Save", command=save_new_inherit_acceptable_components).grid(row=5, column=0, columnspan=2)

def load_prod_position_union(self):

for row in self.tree.get_children():

self.tree.delete(row)

self.cursor.execute("SELECT * FROM prod_position_union")

rows = self.cursor.fetchall()

column_names = [description[0] for description in self.cursor.description]

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=100) # Устанавливаем ширину столбцов

for row in rows:

self.tree.insert("", END, values=row)

# new_object_id, new_component_id, new_quantity

def create_prod_position_union(self):

add_window = Toplevel(self.root)

add_window.title("Add prod position union")

Label(add_window, text="Product name").grid(row=0, column=0)

product_name_entry = Entry(add_window)

product_name_entry.grid(row=0, column=1)

Label(add_window, text="Component product name").grid(row=1, column=0)

component_name_entry = Entry(add_window)

component_name_entry.grid(row=1, column=1)

Label(add_window, text="Quantity").grid(row=2, column=0)

quantity_entry = Entry(add_window)

quantity_entry.grid(row=2, column=1)

def save_new_prod_position_union():

product_name = product_name_entry.get()

component_name = component_name_entry.get()

quantity_str = quantity_entry.get()

try:

quantity = int(quantity_str)

except ValueError:

messagebox.showerror("Error", "Quantity must be a valid integer.")

return

if (quantity <= 0):

messagebox.showerror("Error", f"quantity cant be <= 0.")

return

self.cursor.execute("SELECT id FROM product WHERE product_name = ?", (product_name,))

new_object_id = self.cursor.fetchone()

if new_object_id:

new_object_id = new_object_id[0]

else:

messagebox.showerror("Error", f"Product name with id - '{new_object_id}' not found.")

return

self.cursor.execute("SELECT id FROM product WHERE product_name = ?", (component_name,))

new_component_id = self.cursor.fetchone()

if new_component_id:

new_component_id = new_component_id[0]

else:

messagebox.showerror("Error", f"Component with id - '{new_component_id}' not found.")

return

try:

self.cursor.execute('SELECT id_category FROM product WHERE id = ?', (new_object_id,))

obj_class_id = self.cursor.fetchone()

if obj_class_id is None:

messagebox.showerror("Object ID not found")

return

self.cursor.execute('SELECT id_category FROM product WHERE id = ?', (new_component_id,))

comp_class_id = self.cursor.fetchone()

if comp_class_id is None:

messagebox.showerror("Component ID not found")

return

self.cursor.execute('''

SELECT 1

FROM acceptable_components

WHERE class_id = ? AND component_id = ?

''', (obj_class_id[0], comp_class_id[0]))

if self.cursor.fetchone() is None:

messagebox.showerror("Invalid composition for the object!")

return

self.cursor.execute('''

INSERT INTO prod_position_union (prod_id, comp_id, quantity)

VALUES (?, ?, ?)

''', (new_object_id, new_component_id, quantity))

self.conn.commit()

self.load_prod_position_union()

add_window.destroy()

print('таблица prod_position_union успешно обновлена новым значением.')

return 1 # Success

except Exception as e:

print(f"Error: {e}")

return 0 # Failure

Button(add_window, text="Save", command=save_new_prod_position_union).grid(row=5, column=0, columnspan=2)

def delete_prod_position_union(self):

try:

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

prod_position_union_id = selected_product[0]

self.cursor.execute("DELETE FROM prod_position_union WHERE id = ?", (prod_position_union_id,))

self.conn.commit()

self.load_prod_position_union()

except IndexError:

pass

def delete_acceptable_component(self):

try:

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

acceptable_component_id = selected_product[0]

self.cursor.execute("DELETE FROM acceptable_components WHERE id = ?", (acceptable_component_id,))

self.conn.commit()

self.load_acceptable_component()

except IndexError:

pass

def edit_prod_position_union_quantity(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

prod_position_union_id = selected_product[0]

add_window = Toplevel(self.root)

add_window.title("Enter new quantity")

Label(add_window, text="Product name").grid(row=0, column=0)

quantity_entry = Entry(add_window)

quantity_entry.grid(row=0, column=1)

def save_quantity():

quantity_str = quantity_entry.get()

try:

quantity = int(quantity_str)

except ValueError:

messagebox.showerror("Error", "Quantity must be a valid integer.")

return

if (quantity <= 0):

messagebox.showerror("Error", f"quantity cant be <= 0.")

return

try:

self.cursor.execute('''

UPDATE prod_position_union

SET quantity = ?

WHERE id = ?

''', (quantity, prod_position_union_id))

self.conn.commit()

self.load_prod_position_union()

add_window.destroy()

except IndexError:

pass

Button(add_window, text="Save", command=save_quantity).grid(row=5, column=0, columnspan=2)

def load_acceptable_components_by_class(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

class_id = selected_product[0]

# Clear the treeview

for row in self.tree.get_children():

self.tree.delete(row)

# Fetch component IDs

self.cursor.execute("SELECT component_id FROM acceptable_components WHERE class_id = ?", (class_id,))

component_ids = self.cursor.fetchall()

if not component_ids:

print(f"No components found for class_id {class_id}.")

return

# Fetch component names for each ID

result = []

for component_id in component_ids:

print(f'component_id - {component_id}')

self.cursor.execute("SELECT category_name FROM category WHERE id = ?", (component_id[0],))

name = self.cursor.fetchone()

if name:

print(f'component_id[0], name[0] - {component_id[0], name[0]}')

result.append(( name[0]))

print(f'Для класса с id = {class_id}, составные части: {result}')

for res in result:

print(f'res = {res}')

# Explicitly set up the columns

self.tree["columns"] = ("component_id", "category_name")

self.tree.heading("#0", text="", anchor="w") # Clear default column

self.tree.column("#0", width=0, stretch=False) # Hide the first empty column

for col in self.tree["columns"]:

self.tree.heading(col, text=col, anchor="w")

self.tree.column(col, anchor="w", width=150) # Set width for each column

for row in result:

self.tree.insert("", "end", values=(row[0], row[1]))

def load_find_components_by_object(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

object_id = selected_product[0]

for row in self.tree.get_children():

self.tree.delete(row)

self.cursor.execute("SELECT comp_id, quantity FROM prod_position_union WHERE prod_id = ?", (object_id,))

components = self.cursor.fetchall()

if not components:

return []

result = []

for comp_id, quantity in components:

self.cursor.execute("SELECT product_name, quantity FROM product WHERE id = ?", (comp_id,))

name = self.cursor.fetchone()

if name:

result.append(( [name[0]], [ quantity]))

print(f'для объекта с id = {object_id}, составные части: {result}')

column_names = [description[0] for description in self.cursor.description]

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=100) # Устанавливаем ширину столбцов

for row in result:

self.tree.insert("", END, values=row)

def load_acceptable_components_by_class_recursive(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

class_id = selected_product[0]

for row in self.tree.get_children():

self.tree.delete(row)

def find_components(class_id, result):

self.cursor.execute("SELECT component_id FROM acceptable_components WHERE class_id = ?", (class_id,))

components = self.cursor.fetchall()

for component in components:

component_id = component[0]

result.add(component_id)

find_components(component_id, result)

result = set()

find_components(class_id, result)

component_names = []

for component_id in result:

self.cursor.execute("SELECT category_name FROM category WHERE id = ?", (component_id,))

component_name = self.cursor.fetchone()

if component_name:

component_names.append((component_name[0], component_id))

print(f'результат подходящих компонент для id {class_id} - ({component_names})')

column_names = [description[0] for description in self.cursor.description]

print(f'column_names - - - -{column_names}')

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=120) # Устанавливаем ширину столбцов

for row in component_names:

self.tree.insert("", END, values=row)

# object_id

def find_components_recursive(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

object_id = selected_product[0]

for row in self.tree.get_children():

self.tree.delete(row)

# Recursive function to find components

def find_components(obj_id, result):

self.cursor.execute("SELECT comp_id, quantity FROM prod_position_union WHERE prod_id = ?", (obj_id,))

components = self.cursor.fetchall()

for comp_id, quantity in components:

result[comp_id] = result.get(comp_id, 0) + quantity

find_components(comp_id, result)

result = {}

find_components(object_id, result)

# Fetch component names for the result

final_result = []

for comp_id, total_quantity in result.items():

self.cursor.execute("SELECT product_name FROM product WHERE id = ?", (comp_id,))

name = self.cursor.fetchone()

if name:

final_result.append((name[0], comp_id, total_quantity))

print(f'для объекта с id = {object_id} компоненты, найденные рекурсивно: {final_result}')

column_names = [description[0] for description in self.cursor.description]

print(f'column_names - - - -{column_names}')

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=120) # Устанавливаем ширину столбцов

for row in final_result:

self.tree.insert("", END, values=row)

def load_existing_acceptable_components_by_object(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

object_id = selected_product[0]

for row in self.tree.get_children():

self.tree.delete(row)

self.cursor.execute("SELECT id_category FROM product WHERE id = ?", (object_id,))

id_category = self.cursor.fetchone()[0]

# Find the class_id of the object

self.cursor.execute("SELECT id_parent FROM category WHERE id = ?", (id_category,))

class_info = self.cursor.fetchone()

if not class_info:

return []

class_id = class_info[0]

self.cursor.execute('''

SELECT component_id FROM acceptable_components WHERE class_id = ?

''', (class_id,))

components = self.cursor.fetchall()

# Fetch component names for the result

result = []

for component in components:

component_id = component[0]

self.cursor.execute("SELECT category_name FROM category WHERE id = ?", (component_id,))

name = self.cursor.fetchone()

if name:

# result.append((component_id, name[0]))

result.append((name[0]))

print(f'result - {result}')

column_names = [description[0] for description in self.cursor.description]

print(f'column_names - - - -{column_names}')

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=120) # Устанавливаем ширину столбцов

for row in result:

self.tree.insert("", END, values=row)

def load_existing_acceptable_components_by_object_recursive(self):

selected_item = self.tree.selection()[0]

selected_product = self.tree.item(selected_item)['values']

obj_id = selected_product[0]

self.cursor.execute("SELECT id_category FROM product WHERE id = ?", (obj_id,))

class_id = self.cursor.fetchone()

if not class_id:

return []

class_id = class_id[0]

for row in self.tree.get_children():

self.tree.delete(row)

def find_acceptable_components_by_class_recursive(class_id):

try:

def find_components(class_id, result):

self.cursor.execute("SELECT component_id FROM acceptable_components WHERE class_id = ?", (class_id,))

components = self.cursor.fetchall()

for component in components:

component_id = component[0]

result.add(component_id)

find_components(component_id, result)

result = set()

find_components(class_id, result)

# Fetch component names for the result set

component_names = []

for component_id in result:

self.cursor.execute("SELECT category_name FROM category WHERE id = ?", (component_id,))

component_name = self.cursor.fetchone()

if component_name:

component_names.append((component_id, component_name[0]))

print(f'результат подходящих компонент для id {class_id} - ({component_names})')

return component_names

except Exception as e:

print(f"Error occurred while finding acceptable components: {e}")

return []

def find_components(cl_id):

components = []

acceptable_components = find_acceptable_components_by_class_recursive(cl_id)

for component in acceptable_components:

component_id = component[0]

self.cursor.execute("SELECT id, product_name FROM product WHERE id_category = ?", (component_id,))

obj_data = self.cursor.fetchone()

if obj_data:

# components.append({

# obj_data[1]

# })

components.append({

'component_name': obj_data[1],

'component_id': obj_data[0]

})

return components

components = find_components(class_id)

column_names = [description[0] for description in self.cursor.description]

print(f'column_names - - - -{column_names}')

self.tree["columns"] = column_names

for col in self.tree["columns"]:

self.tree.heading(col, text=col)

self.tree.column(col, width=120)

for row in components:

self.tree.insert("", END, values=(row['component_id'], row['component_name']))

# coursework-2

def __del__(self):

self.conn.close()

Вывод

В ходе курсовой работы был разработан пользовательский интерфейс для смоделированного спецификации изделий (Bill of materials). Были разработаны функции создания, удаления, изменения информации в базе данных изделия, допустимые компоненты, позиции многосоставных продуктов. А также удаления данных и заполнения базы данных тестовым примером

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