
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). Были разработаны функции создания, удаления, изменения информации в базе данных изделия, допустимые компоненты, позиции многосоставных продуктов. А также удаления данных и заполнения базы данных тестовым примером