
Добавил:
hiiamfool
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
# -*- coding: utf-8 -*-
import sqlite3
path = "C:/Users/admin/source/repos/UNIVERSITY_repos/4 course/7 sem/mispris/2-4/furniture.db"
# path = "/home/user/repos/mispris/3/furniture.db"
conn = sqlite3.connect(path)
cursor = conn.cursor()
conn.execute("PRAGMA foreign_keys = ON")
print("\n\nDB has been created/connected\n")
ACCEPTABLE_COMPONENTS_TABLE = 'acceptable_components'
CLASS_PARAM_TABLE = 'class_param'
ENUM_TABLE = 'enum'
INPUT_RESOURCES_TABLE = 'input_resources'
PARAM_TABLE = 'param'
PROD_OPERATION_TABLE = 'prod_operation'
PROD_PARAM_TABLE = 'prod_param'
PROD_POSITION_UNION_TABLE = 'prod_position_union'
PRODUCT_TABLE = 'product'
TERMINAL_CLASSIFIER_TABLE = 'terminal_classifier'
UNIT_TABLE = 'unit'
FUNC_TABLE = 'func'
PREDICATE_TABLE = 'predicate'
FUNC_BODY_TABLE = 'func_body'
PROD_SPEC_TABLE = 'prod_spec'
ENUM_OPERATORS_CLASS_NAME = 'перечисление операторов'
ENUM_PARAMS_VALUE = 'перечисление значений параметров'
def create_unit_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS unit (
id INTEGER PRIMARY KEY AUTOINCREMENT,
unit_name TEXT UNIQUE,
unit_name_short TEXT UNIQUE
)
''')
conn.commit()
def create_terminal_classifier_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS terminal_classifier (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id_parent INTEGER CHECK (id_parent != id),
terminal_classifier_name TEXT NOT NULL,
terminal_classifier_short_name TEXT NOT NULL,
id_unit INTEGER,
priority INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (id_unit) REFERENCES unit(id) ON DELETE CASCADE,
FOREIGN KEY (id_parent) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_enum_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS enum (
id INTEGER PRIMARY KEY AUTOINCREMENT,
enum_id INTEGER,
enum_name TEXT NOT NULL,
enum_short_name TEXT NOT NULL,
enum_description TEXT,
real_value REAL,
int_value INTEGER,
str_value TEXT,
priority INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (enum_id) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_product_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS product (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id_category INTEGER,
configurable_type INTEGER NOT NULL DEFAULT 0,
product_name_short TEXT,
product_name TEXT NOT NULL,
quantity INTEGER,
price REAL,
unit_value REAL,
place INTEGER,
FOREIGN KEY (id_category) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_param_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS param (
id INTEGER PRIMARY KEY AUTOINCREMENT,
param_name TEXT NOT NULL,
param_short_name TEXT NOT NULL,
unit_id INTEGER,
min_val REAL,
max_val REAL,
FOREIGN KEY (unit_id) REFERENCES unit(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_class_param_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS class_param (
id INTEGER PRIMARY KEY AUTOINCREMENT,
param_id INTEGER NOT NULL,
class_param_id INTEGER,
param_class_name TEXT NOT NULL,
param_class_short_name TEXT NOT NULL,
priority INTEGER NOT NULL,
FOREIGN KEY (param_id) REFERENCES param(id) ON DELETE CASCADE,
FOREIGN KEY (class_param_id) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
##################################### modified due to 2-3 lab
def create_prod_param_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS prod_param (
id INTEGER PRIMARY KEY AUTOINCREMENT,
prod_id INTEGER NOT NULL,
param_id INTEGER NOT NULL,
is_configurable BOOLEAN NOT NULL DEFAULT FALSE,
int_value INTEGER,
str_value TEXT,
real_value REAL,
enum_value TEXT,
class_value INTEGER,
UNIQUE (prod_id, param_id),
FOREIGN KEY (param_id) REFERENCES param(id) ON DELETE CASCADE,
FOREIGN KEY (prod_id) REFERENCES product(id) ON DELETE CASCADE
)
''')
conn.commit()
##################################### modified due to 2-3 lab
##################################### 2-1 lab #####################################
def create_acceptable_components_table():
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 terminal_classifier(id) ON DELETE CASCADE,
FOREIGN KEY (component_id) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_prod_position_union_table():
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
)
''')
conn.commit()
##################################### 2-1 lab #####################################
##################################### 2-2 lab #####################################
def create_prod_operation_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS prod_operation (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id_operation_type INTEGER NOT NULL,
operation_name TEXT NOT NULL,
operation_priority REAL NOT NULL,
id_shd INTEGER NOT NULL,
prod_id INTEGER NOT NULL,
grc_id INTEGER NOT NULL,
prof_id INTEGER NOT NULL,
prof_qual_id INTEGER,
launch_time REAL NOT NULL,
time_per_obj REAL NOT NULL,
time_unit_id INTEGER NOT NULL,
FOREIGN KEY (id_shd) REFERENCES terminal_classifier(id) ON DELETE CASCADE,
FOREIGN KEY (prod_id) REFERENCES product(id) ON DELETE CASCADE,
FOREIGN KEY (grc_id) REFERENCES terminal_classifier(id) ON DELETE RESTRICT,
FOREIGN KEY (prof_id) REFERENCES terminal_classifier(id) ON DELETE RESTRICT,
FOREIGN KEY (prof_qual_id) REFERENCES enum(id) ON DELETE RESTRICT,
FOREIGN KEY (time_unit_id) REFERENCES unit(id) ON DELETE RESTRICT
);
''')
conn.commit()
def create_input_resources_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS input_resources (
id INTEGER PRIMARY KEY AUTOINCREMENT,
operation_id INTEGER NOT NULL,
prod_id INTEGER NOT NULL,
resource_name TEXT NOT NULL,
unit_id INTEGER NOT NULL,
quantity REAL NOT NULL,
FOREIGN KEY (operation_id) REFERENCES prod_operation(id) ON DELETE CASCADE,
FOREIGN KEY (prod_id) REFERENCES product(id) ON DELETE RESTRICT
FOREIGN KEY (unit_id) REFERENCES unit(id) ON DELETE RESTRICT
);
""")
conn.commit()
##################################### 2-2 lab #####################################
##################################### 2-3 lab #####################################
def create_orders_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer INTEGER NOT NULL,
contact_person INTEGER,
order_time TEXT NOT NULL,
order_completion_time TEXT,
FOREIGN KEY (customer) REFERENCES terminal_classifier(id),
FOREIGN KEY (contact_person) REFERENCES product(id)
);
""")
conn.commit()
def create_orders_pos_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS orders_pos (
order_id INTEGER NOT NULL,
prod_id INTEGER NOT NULL,
quantity INTEGER NOT NULL,
PRIMARY KEY (order_id, prod_id),
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (prod_id) REFERENCES product(id)
);
""")
conn.commit()
##################################### 2-3 lab #####################################
##################################### 2-4 lab #####################################
def create_func_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS func (
id INTEGER PRIMARY KEY AUTOINCREMENT,
class_id INTEGER NOT NULL,
name TEXT NOT NULL,
FOREIGN KEY (class_id) REFERENCES terminal_classifier(id) ON UPDATE CASCADE ON DELETE CASCADE
);
""")
conn.commit()
## замечания, касательно различий реализации:
# у Владоса есть таблица ENUM_POS, у меня, видимо, это просто таблица enum, а сами классы для enum заданы в таблице terminal_classifier
def create_predicate_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS predicate (
id INTEGER PRIMARY KEY AUTOINCREMENT,
operator_id INTEGER NOT NULL,
param_id INTEGER NOT NULL,
enum_pos_id INTEGER NOT NULL,
FOREIGN KEY (param_id) REFERENCES param(id) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (enum_pos_id) REFERENCES enum(id) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (operator_id) REFERENCES enum(id) ON UPDATE CASCADE ON DELETE RESTRICT
);
""")
conn.commit()
def create_func_body_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS func_body (
func_id INTEGER NOT NULL,
conjunction_num INTEGER NOT NULL CHECK (conjunction_num >= 0),
predicate_id INTEGER NOT NULL,
inversio BOOLEAN NOT NULL DEFAULT FALSE,
PRIMARY KEY (func_id, conjunction_num, predicate_id),
FOREIGN KEY (func_id) REFERENCES func(id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (predicate_id) REFERENCES predicate(id) ON UPDATE CASCADE ON DELETE RESTRICT
);
""")
conn.commit()
def create_prod_spec_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS prod_spec (
prod_id INTEGER NOT NULL,
func_id INTEGER NOT NULL,
PRIMARY KEY (prod_id, func_id),
FOREIGN KEY (func_id) REFERENCES func(id) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (prod_id) REFERENCES product(id) ON UPDATE CASCADE ON DELETE CASCADE
);
""")
conn.commit()
##################################### 2-4 lab #####################################
def creating_tables():
create_unit_table()
create_terminal_classifier_table()
create_enum_table()
create_product_table()
create_param_table()
create_class_param_table()
create_prod_param_table()
#2-1 lab#
create_acceptable_components_table()
create_prod_position_union_table()
#2-1 lab#
#2-2 lab#
create_prod_operation_table()
create_input_resources_table()
#2-2 lab#
#2-3 lab#
create_orders_table()
create_orders_pos_table()
#2-3 lab#
#2-4 lab#
create_func_table()
create_predicate_table()
create_func_body_table()
create_prod_spec_table()
#2-4 lab#
creating_tables()
def delete_data(tables_order):
try:
cursor.execute("PRAGMA foreign_keys = OFF;") # Disable foreign key checks
for table_name in tables_order:
cursor.execute(f"DELETE FROM {table_name};")
conn.commit()
cursor.execute("PRAGMA foreign_keys = ON;") # Re-enable foreign key checks
except sqlite3.Error as ex:
print(f"Произошла ошибка при удалении данных: {ex}")
conn.rollback()
def dropAllTables():
try:
cursor.execute("PRAGMA foreign_keys = OFF;") # Temporarily disable FK constraints
# List all tables in dependency order (most dependent first)
tables_order = [
'prod_spec', # Depends on 'func' and 'product'
'func_body', # Depends on 'func' and 'predicate'
'predicate', # Depends on 'param' and 'enum'
'func', # Depends on 'terminal_classifier'
'orders_pos', # Depends on 'orders' and 'product'
'input_resources', # Child of 'prod_operation' and 'product'
'prod_operation', # Child of 'product', 'unit', etc.
'prod_param', # Child of 'product', 'param', 'enum'
'orders', # Depends on 'product'
'acceptable_components',# Child of 'terminal_classifier'
'prod_position_union', # Child of 'product'
'product', # Child of 'terminal_classifier'
'enum', # Child of 'terminal_classifier'
'class_param', # Child of 'param', 'terminal_classifier'
'param', # Child of 'unit'
'terminal_classifier', # Child of 'unit'
'unit' # No dependencies
]
# Check and drop each table only if it exists
for table_name in tables_order:
cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}'")
if cursor.fetchone(): # Drop only if the table exists
cursor.execute(f"DROP TABLE IF EXISTS {table_name};")
conn.commit()
cursor.execute("PRAGMA foreign_keys = ON;") # Re-enable FK constraints
print("Все таблицы успешно удалены.")
except sqlite3.Error as ex:
print(f"Произошла ошибка при удалении таблиц: {ex}")
conn.rollback()
def is_category_exists(terminal_classifier_name):
cursor.execute("SELECT COUNT(*) FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
count = cursor.fetchone()[0]
res = count > 0
return res
def is_category_id_exists(cl_id):
cursor.execute("SELECT COUNT(*) FROM terminal_classifier WHERE id = ?", (cl_id,))
count = cursor.fetchone()[0]
res = count > 0
return res
def is_product_exist(product_name):
cursor.execute("SELECT COUNT(*) FROM product WHERE product_name = ?", (product_name,))
count = cursor.fetchone()[0]
res = count > 0
return res
def is_unit_exist(unit_name_short):
cursor.execute("SELECT COUNT(*) FROM unit WHERE unit_name_short = ?", (unit_name_short,))
count = cursor.fetchone()[0]
res = count > 0
return res
def add_unit(unit_name, unit_name_short):
try:
if not is_unit_exist(unit_name_short):
cursor.execute('''
INSERT INTO unit (unit_name, unit_name_short)
VALUES (?, ?)
''', (unit_name, unit_name_short))
conn.commit()
print('Единица измерения успешно добавлена.')
else:
print('Единица измерения с таким названием уже существует.')
except Exception as _ex:
print(f'Error {_ex} - произошла ошибка при добавлении единицы измерения')
def add_category(terminal_classifier_name, terminal_classifier_short_name, id_parent=None, id_unit=None):
try:
if is_category_exists(terminal_classifier_name):
raise ValueError(f'Категория с названием {terminal_classifier_name} уже существует.')
if id_unit:
cursor.execute("SELECT COUNT(*) FROM unit WHERE id = ?", (id_unit,))
unit_check_exist = cursor.fetchone()[0]
if not unit_check_exist:
raise ValueError(f'Указанного id единицы измерения не существует!')
cursor.execute('''
INSERT INTO terminal_classifier (terminal_classifier_name, terminal_classifier_short_name, id_parent, id_unit)
VALUES (?, ?, ?, ?)
''', (terminal_classifier_name, terminal_classifier_short_name, id_parent, id_unit))
conn.commit()
print('Категория успешно добавлена.')
except Exception as _ex:
print(f'Error {_ex} - ошибка при добавлении категории.')
def add_subcategory(terminal_classifier_name, subterminal_classifier_name, subterminal_classifier_short_name, id_unit=None):
try:
if is_category_exists(terminal_classifier_name):
# Получаем Id категории
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_parent_to_set = cursor.fetchone()[0]
add_category(subterminal_classifier_name, subterminal_classifier_short_name, id_parent_to_set, id_unit)
conn.commit()
print("Подкатегория успешно добавлена.")
else:
print("Указанная категория/подкатегория не существует.")
except Exception as _ex:
print(f"Произошла ошибка при добавлении подкатегории: {_ex}")
def edit_category(id, terminal_classifier_name_new, terminal_classifier_short_name_new, id_unit=None):
try:
cursor.execute('SELECT COUNT(*) FROM terminal_classifier WHERE id = ?', (id,))
if cursor.fetchone()[0] == 0:
raise ValueError(f"Запись с id={id} не найдена в таблице terminal_classifier.")
if id_unit is not None:
cursor.execute('SELECT COUNT(*) FROM unit WHERE id = ?', (id_unit,))
if cursor.fetchone()[0] == 0:
raise ValueError(f"Запись с id_unit={id_unit} не найдена в таблице unit.")
cursor.execute('SELECT COUNT(*) FROM terminal_classifier WHERE terminal_classifier_name = ? AND id != ?', (terminal_classifier_name_new, id))
if cursor.fetchone()[0] > 0:
raise ValueError(f"Новое полное имя '{terminal_classifier_name_new}' уже занято.")
cursor.execute('SELECT COUNT(*) FROM terminal_classifier WHERE terminal_classifier_short_name = ? AND id != ?', (terminal_classifier_short_name_new, id))
if cursor.fetchone()[0] > 0:
raise ValueError(f"Новое короткое имя '{terminal_classifier_short_name_new}' уже занято.")
cursor.execute('''
UPDATE terminal_classifier
SET terminal_classifier_name = ?,
terminal_classifier_short_name = ?,
id_unit = ?
WHERE id = ?
''', (terminal_classifier_name_new, terminal_classifier_short_name_new, id_unit, id))
# Подтверждаем изменения
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при изменении категории: {_ex}")
def add_product(product_name, terminal_classifier_name, quantity, price, unit_value ):
try:
if is_category_exists(terminal_classifier_name):
# Получаем id подкатегории по ее названию
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
category_id = cursor.fetchone()[0]
# Добавляем новое изделие в таблицу Изделие
cursor.execute("INSERT INTO product (id_category, product_name, quantity, price, unit_value) VALUES (?, ?, ?, ?, ?)",
(category_id, product_name, quantity, price, unit_value))
conn.commit()
print("Изделие успешно добавлено.")
else:
print("Указанная подкатегория не существует.")
except Exception as _ex:
print(f"Произошла ошибка при добавлении изделия: {_ex}")
def get_all_categories():
try:
cursor.execute("SELECT * FROM terminal_classifier")
categories_names = cursor.fetchall()
return categories_names
except Exception as _ex:
print(f"Произошла ошибка при получении категорий: {_ex}")
return None
def get_all_products():
try:
cursor.execute("SELECT * FROM product")
products_names = cursor.fetchall()
return products_names
except Exception as _ex:
print(f"Произошла ошибка при получении товаров: {_ex}")
return None
def product_update_price(product_name, new_price):
try:
if is_product_exist(product_name):
cursor.execute("UPDATE product SET price = ? WHERE product_name = ?", (new_price, product_name))
conn.commit()
print('Цена изделия успешно обновлена.')
else:
print('Указанное изделие не существует.')
except Exception as _ex:
print(f"Произошла ошибка при обновлении цены изделия: {_ex}")
def product_update_quantity(product_name, new_quantity):
try:
if is_product_exist(product_name):
cursor.execute("UPDATE product SET quantity = ? WHERE product_name = ?", (new_quantity, product_name))
conn.commit()
print('Количество изделия успешно обновлено.')
else:
print('Указанное изделие не существует.')
except Exception as _ex:
print(f"Произошла ошибка при обновлении цены изделия: {_ex}")
def change_product_category(product_name, new_category):
try:
if is_category_exists(new_category):
# Получаем идентификатор новой категории
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (new_category,))
new_category_id = cursor.fetchone()[0]
# Обновляем категорию у изделия
cursor.execute("UPDATE product SET id_category = ? WHERE product_name = ?", (new_category_id, product_name))
conn.commit()
print('Категория изделия успешно изменена.')
else:
print('Указанная новая подкатегория не существует.')
except Exception as _ex:
print(f"Произошла ошибка при изменении подкатегории изделия: {_ex}")
def change_product_unit_value(product_name, unit_value):
try:
if is_product_exist(product_name):
cursor.execute("UPDATE product SET unit_value = ? WHERE product_name = ?", (unit_value, product_name))
conn.commit()
print('Значение единицы измерения изделия успешно изменено.')
else:
print('Указанное изделие не существует.')
except Exception as _ex:
print(f"Произошла ошибка при изменении значения единицы измерения изделия: {_ex}")
def delete_product_unit_value(product_name):
try:
if is_product_exist(product_name):
# cursor.execute("SELECT id_unit FROM product WHERE product_name = ?", (product_name,))
# delete_unit_id = cursor.fetchone()[0]
cursor.execute("UPDATE product SET unit_value = ? WHERE product_name = ?", (None, product_name))
conn.commit()
print('Значение единицы измерения изделия успешно удалено.')
else:
print('Указанное изделие не существует.')
except Exception as _ex:
print(f"Произошла ошибка при удалении значения единицы измерения изделия: {_ex}")
def is_enum_exist(terminal_classifier_name):
try:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
check_if_exist = cursor.fetchone()
return check_if_exist
except Exception as _ex:
print(f"Произошла ошибка при проверке перечисления на существование: {_ex}")
def is_enum_pos_exist(enum_name):
try:
cursor.execute("SELECT id FROM enum WHERE enum_name = ?", (enum_name,))
check_if_exist = cursor.fetchone()
if check_if_exist:
return True
else:
return False
except Exception as _ex:
print(f"Произошла ошибка при проверке перечисления на существование: {_ex}")
def add_enum_pos(enum_id, enum_name, enum_short_name, enum_description=None, real_value=None, int_value=None, str_value=None, priority=None):
try:
if is_enum_pos_exist(enum_name) and (not (enum_name == 'значение параметра' and enum_short_name == 'знчн прмтр')):
print("Указанное перечисление уже существует.")
return
# Get next priority if not provided
if priority is None:
cursor.execute("SELECT COALESCE(MAX(priority), 0) + 1 FROM enum", ())
priority = cursor.fetchone()[0]
# UPDATE via id
cursor.execute("INSERT INTO enum (enum_id, enum_name, enum_short_name, enum_description, real_value, int_value, str_value, priority) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
(enum_id, enum_name, enum_short_name, enum_description, real_value, int_value, str_value, priority))
conn.commit()
print('Перечисление успешно добавлено.')
except Exception as _ex:
print(f"Произошла ошибка при добавлении перечисления: {_ex}")
def delete_enum_classification(terminal_classifier_name):
try:
if is_enum_exist(terminal_classifier_name):
# Получаем идентификатор удаляемого класса перечислений
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
delete_id = cursor.fetchone()[0]
# Перемещаем все классы перечисления удаляемого класса перечисления в класс-перечисление "неопределенные"
cursor.execute("UPDATE terminal_classifier SET id_parent = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'неопределенные') WHERE id_parent = ?", (delete_id,))
# Перемещаем все перечисления удаляемой категории в категорию "неопределенные"
cursor.execute("UPDATE enum SET enum_id = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'неопределенные') WHERE enum_id = ?", (delete_id,))
# Удаляем класс-перечисление
cursor.execute("DELETE FROM terminal_classifier WHERE id = ?", (delete_id,))
conn.commit()
print('Класс перечисления успешно удален.')
else:
print('Указанный класс перечисления не существует.')
except Exception as _ex:
print(f"Произошла ошибка при удалении класса перечисления: {_ex}")
def delete_enum_pos(enum_name):
try:
# Удаление перечисления
cursor.execute("DELETE FROM enum WHERE enum_name = ?", (enum_name,))
rows_deleted = cursor.rowcount
if rows_deleted > 0:
print('Перечисление успешно удалено.')
else:
print('Перечисление с указанным названием не найдено.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при удалении перечисления: {_ex}")
def change_enum_pos(id, new_enum_name, new_enum_short_name, new_enum_description=None, new_real_value=None, new_int_value=None, new_str_value=None):
try:
cursor.execute("SELECT enum_name FROM enum WHERE id = ?", (id,))
old_name_to_check = cursor.fetchone()[0]
if is_enum_pos_exist(old_name_to_check):
cursor.execute("UPDATE enum SET enum_name = ?, enum_short_name = ?, enum_description = ?, real_value = ?, int_value = ?, str_value = ? WHERE id = ?",
(new_enum_name, new_enum_short_name, new_enum_description, new_real_value, new_int_value, new_str_value, id))
conn.commit()
print('Перечисление изменено.')
else:
print('Указаное перечисление не найдено.')
return
except Exception as _ex:
print(f"Произошла ошибка при изменении перечисления: {_ex}")
def edit_enum_pos_priority(enum_pos_id, new_priority):
try:
# Получаем enum_id для указанного enum_pos_id
cursor.execute("SELECT enum_id FROM enum WHERE id = ?", (enum_pos_id,))
result = cursor.fetchone()
if result is None:
print('Указанное enum_pos_id не найдено.')
return None
enum_id = result[0]
# Проверяем, существует ли уже запись с таким priority для данного enum_id
cursor.execute("""
SELECT count(*)
FROM enum
WHERE priority = ?
AND enum_id = ?
""", (new_priority, enum_id))
count = cursor.fetchone()[0]
if count == 0:
# Обновляем priority
cursor.execute("""
UPDATE enum
SET priority = ?
WHERE id = ?
""", (new_priority, enum_pos_id))
else:
# Смещаем приоритеты и обновляем нужную запись
cursor.execute("""
UPDATE enum
SET priority = priority + 1
WHERE priority >= ?
AND enum_id = ?
""", (new_priority, enum_id))
cursor.execute("""
UPDATE enum
SET priority = ?
WHERE id = ?
""", (new_priority, enum_pos_id))
conn.commit()
print("Приоритет перечисления изменен")
return new_priority
except Exception as _ex:
print(f"Произошла ошибка при изменении приоритета перечисления: {_ex}")
def find_enums(enum_class_id):
try:
cursor.execute("""
SELECT ep.id, ep.enum_name, ep.enum_short_name, ep.enum_id, ep.priority, ep.real_value, ep.int_value, ep.str_value
FROM enum ep
WHERE ep.enum_id = ?
ORDER BY ep.priority ASC
""", (enum_class_id,))
results = cursor.fetchall()
for row in results:
print(row)
return results
except Exception as _ex:
print(f"Произошла ошибка при получении списка перечислений заданного класса: {_ex}")
def add_enum_in_classifier(terminal_classifier_name, terminal_classifier_short_name, enum_parent_name, id_unit=None):
try:
if (is_category_exists(terminal_classifier_name)):
raise ValueError(f'перечисление с именем \"{terminal_classifier_name}\" уже существует в таблице {TERMINAL_CLASSIFIER_TABLE}')
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (enum_parent_name,))
id_parent_check = cursor.fetchone()
if id_parent_check is not None:
id_parent = id_parent_check[0]
else:
id_parent = None
if id_unit:
cursor.execute("SELECT COUNT(*) FROM unit WHERE id = ?", (id_unit,))
count = cursor.fetchone()[0]
if (not count):
print(f'Произошла ошибка при добавлении записи в enum_classifier! Указанного id_unit не существует.')
cursor.execute('''
INSERT INTO terminal_classifier (terminal_classifier_name, terminal_classifier_short_name, id_parent, id_unit)
VALUES (?, ?, ?, ?)
''', (terminal_classifier_name, terminal_classifier_short_name, id_parent, id_unit))
conn.commit()
print('Класс перечисления успешно добавлен в основную базу.')
except Exception as _ex:
print(f'Error {_ex} - ошибка при добавлении enum_in_classifier.')
def change_enum_priority(enum_name, priority):
try:
if (priority >= 0):
cursor.execute("UPDATE enum SET priority = ? WHERE enum_name = ?", (priority, enum_name))
conn.commit()
else:
print('Приоритет должен быть неотрицательным целым числом.')
return
except Exception as _ex:
print(f'Error {_ex} - ошибка при изменении приоритета конкретного перечисления.')
def check_cyclic_dependency_terminal_classifier(new_parent_terminal_classifier_id, product_name_in_func):
try:
def fetch_parent_terminal_classifier(id):
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE id = ?", (id,))
return cursor.fetchone()[0]
current_id = new_parent_terminal_classifier_id
while current_id is not None:
if current_id == product_name_in_func:
return True
current_id = fetch_parent_terminal_classifier(current_id)
return False
except Exception as _ex:
print(f'Error {_ex} - ошибка при проверке классов на цикл.')
def change_parent_of_terminal_classifier(terminal_classifier_name, new_parent_terminal_classifier=None):
try:
print(f'введенные категории - для {terminal_classifier_name} назначить родителем {new_parent_terminal_classifier}')
if (is_enum_exist(terminal_classifier_name)):
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_enum = cursor.fetchone()[0]
if (new_parent_terminal_classifier is not None):
if (is_enum_exist(new_parent_terminal_classifier)):
if (terminal_classifier_name == new_parent_terminal_classifier):
print('Нельзя назначить классу самого себя в родители.')
return 0
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (new_parent_terminal_classifier,))
id_new_parent_terminal_classifier = cursor.fetchone()[0]
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_parent_class_of_class = cursor.fetchone()[0]
# Check for cyclic dependency using the recursive function
if check_cyclic_dependency_terminal_classifier(id_new_parent_terminal_classifier, id_enum):
if (id_parent_class_of_class):
# if parent class has had their own parent then would set it
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_new_parent_terminal_classifier, id_enum))
conn.commit()
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_parent_class_of_class, id_new_parent_terminal_classifier ))
conn.commit()
print('Родитель у подкласса был успешно изменен.')
return 1
else:
# if not then class becomes root
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE terminal_classifier_name = ?", (None, new_parent_terminal_classifier))
conn.commit()
print(f'Подкласс c terminal_classifier_name - {new_parent_terminal_classifier} стала родительской.')
return 1
# Update the parent class
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_new_parent_terminal_classifier, id_enum ))
conn.commit()
return 1
else:
print('Новая родительский класс не существует.')
return 0
else:
# code for new_parent_class=None
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (None, id_enum))
conn.commit()
print('Класс стал корневым / одним из корневых')
return 1
else:
print('Указанного класса не существует.')
return 0
except Exception as _ex:
conn.rollback()
print(f"Ошибка в изменении родителя класса (terminal_classifier): {_ex}")
def delete_product(product_name):
try:
# Удаление изделия
cursor.execute("DELETE FROM product WHERE product_name = ?", (product_name,))
rows_deleted = cursor.rowcount
if rows_deleted > 0:
print('Изделие успешно удалено.')
else:
print('Изделие с указанным названием не найдено.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при удалении изделия: {_ex}")
def delete_product_by_id(prod_id):
try:
# Удаление изделия
cursor.execute("DELETE FROM product WHERE id = ?", (prod_id,))
rows_deleted = cursor.rowcount
if rows_deleted > 0:
print('Изделие успешно удалено.')
else:
print('Изделие с указанным id не найдено.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при удалении изделия: {_ex}")
def delete_category(terminal_classifier_name):
try:
if is_category_exists(terminal_classifier_name):
# Получаем идентификатор удаляемой категории
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?;", (terminal_classifier_name,))
delete_id = cursor.fetchone()[0]
# Перемещаем все подкатегории удаляемой категории в категорию "неопределенные"
cursor.execute("UPDATE terminal_classifier SET id_parent = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'неопределенные') WHERE id_parent = ?", (delete_id,))
# Перемещаем все изделия удаляемой категории в категорию "неопределенные"
cursor.execute("UPDATE product SET id_category = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'неопределенные') WHERE id_category = ?", (delete_id,))
# Удаляем категорию
cursor.execute("DELETE FROM terminal_classifier WHERE id = ?", (delete_id,))
conn.commit()
print('Категория успешно удалена.')
else:
print('Указанная категория не существует.')
except Exception as _ex:
print(f"Произошла ошибка при удалении категории: {_ex}")
# вроде воркает с подтягиванием к 1 ноде 3ей ноды, при удалении 2
def delete_subcategory(subterminal_classifier_name):
try:
if is_category_exists(subterminal_classifier_name):
# Получаем идентификатор и родительский идентификатор удаляемой подкатегории
cursor.execute("SELECT id, id_parent FROM terminal_classifier WHERE terminal_classifier_name = ?", (subterminal_classifier_name,))
result = cursor.fetchone()
if not result:
print('Указанная подкатегория не существует.')
return
subcategory_id, parent_id = result
# Если есть родительская категория
if parent_id:
# Обновляем родителя потомков удаляемой подкатегории на родителя удаляемой подкатегории
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id_parent = ?", (parent_id, subcategory_id))
else:
# Если родителя нет, перемещаем детей в "категория неопределенное"
cursor.execute("UPDATE terminal_classifier SET id_parent = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'категория неопределенное') WHERE id_parent = ?", (subcategory_id,))
# Перемещаем связанные изделия в категорию "неопределенные"
cursor.execute("UPDATE product SET id_category = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'категория неопределенное') WHERE id_category = ?", (subcategory_id,))
# Удаляем подкатегорию
cursor.execute("DELETE FROM terminal_classifier WHERE id = ?", (subcategory_id,))
conn.commit()
print('Подкатегория успешно удалена.')
else:
print('Указанная подкатегория не существует.')
except Exception as _ex:
print(f"Произошла ошибка при удалении подкатегории: {_ex}")
def get_subcategory_parent(subterminal_classifier_name):
try:
if is_category_exists(subterminal_classifier_name):
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE terminal_classifier_name = ?", (subterminal_classifier_name,))
id_parent_category_of_subcategory = cursor.fetchone()[0]
cursor.execute("SELECT terminal_classifier_name FROM terminal_classifier WHERE id = ?", (id_parent_category_of_subcategory,))
parent_terminal_classifier_name = cursor.fetchone()[0]
return parent_terminal_classifier_name
else:
print('Указанной подкатегории не существует!')
except Exception as _ex:
print(f"Произошла ошибка при получении родительской категории подкатегории: {_ex}")
# cycle checking
def check_cyclic_dependency(new_parent_id, category_id):
def fetch_parent_category(cat_id):
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE id = ?", (cat_id,))
return cursor.fetchone()[0]
current_id = new_parent_id
while current_id is not None:
if current_id == category_id:
return True
current_id = fetch_parent_category(current_id)
return False
def change_parent_of_category(terminal_classifier_name, new_parent_category=None):
try:
print(f'введенные категории - для {terminal_classifier_name} назначить родителем {new_parent_category}')
if (is_category_exists(terminal_classifier_name)):
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_category = cursor.fetchone()[0]
if (new_parent_category is not None):
if (is_category_exists(new_parent_category)):
if (terminal_classifier_name == new_parent_category):
print('Нельзя назначить категории саму себя в родители.')
return
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (new_parent_category,))
id_new_parent_category = cursor.fetchone()[0]
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_parent_category_of_category = cursor.fetchone()[0]
# Check for cyclic dependency using the recursive function
if check_cyclic_dependency(id_new_parent_category, id_category):
if (id_parent_category_of_category):
# if parent category has had their own parent then would set it
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_new_parent_category, id_category))
conn.commit()
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_parent_category_of_category, id_new_parent_category ))
conn.commit()
print('Родитель у подкатегории был успешно изменен.')
else:
# if not then category becomes root
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE terminal_classifier_name = ?", (None, new_parent_category))
conn.commit()
print(f'Подкатегория c terminal_classifier_name {new_parent_category} стала родительской.')
# Update the parent category
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_new_parent_category, id_category ))
conn.commit()
else:
print('Новая родительская категория не существует.')
else:
# code for new_parent_category=None
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (None, id_category))
conn.commit()
print('Категория стала корневой / одной из корневых')
else:
print('Указанной категории не существует.')
except Exception as _ex:
conn.rollback()
print(f"Ошибка в изменении родителя категории: {_ex}")
def change_terminal_classifier_name(old_name, new_name):
try:
if is_category_exists(old_name):
if not is_category_exists(new_name):
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (old_name,))
terminal_classifier_name_id = cursor.fetchone()[0]
cursor.execute("UPDATE category SET terminal_classifier_name = ? WHERE id = ?", (new_name, terminal_classifier_name_id))
print('Имя категории успешно изменено.')
else:
print('Указанное новое имя категории уже существует!')
else:
print('Указанная категория не существует.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при изменении имени категории: {_ex}")
def change_product_name(old_name, new_name):
try:
if is_product_exist(old_name):
if not is_product_exist(new_name):
cursor.execute("SELECT id FROM product WHERE product_name = ?", (old_name,))
product_name_id = cursor.fetchone()[0]
cursor.execute("UPDATE product SET product_name = ? WHERE id = ?", (new_name, product_name_id))
print('Имя изделия успешно изменено.')
else:
print('Указанное новое имя изделия уже существует!')
else:
print('Указанное изделие не существует.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при изменении имени изделия: {_ex}")
def get_category_parents(terminal_classifier_name):
if is_category_exists(terminal_classifier_name):
terminal_classifier_name_copy = terminal_classifier_name
try:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
category_id = cursor.fetchone()[0]
# function for recursive search parents
def find_parents(category_id, parents_list):
id_parent = 0
cursor.execute("SELECT EXISTS(SELECT 1 FROM terminal_classifier WHERE id = ?)", (category_id,))
record_exists = cursor.fetchone()[0]
if record_exists:
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE id = ?", (category_id,))
id_parent = cursor.fetchone()[0]
if id_parent == 0:
return
if category_id != 0 and id_parent != 0:
if id_parent != 0:
cursor.execute("SELECT terminal_classifier_name FROM terminal_classifier WHERE id = ?", (id_parent,))
parent_name = cursor.fetchone()
parents_list.append(parent_name)
find_parents(id_parent, parents_list)
parents_list = []
parents_list_res = []
# begin recursive search for parents
find_parents(category_id, parents_list)
for elem in parents_list:
if elem:
parents_list_res.append(elem[0])
if parents_list_res:
print(f'родительские элементы для категории "{terminal_classifier_name_copy}": \n {parents_list_res}')
else:
print(f'У категории "{terminal_classifier_name_copy}" нет родительских элементов')
except Exception as _ex:
print(f"Произошла ошибка при получении списка родителей категории: {_ex}")
else:
print('Категории не существует.')
def print_category_children(terminal_classifier_name, order):
if not is_category_exists(terminal_classifier_name):
print("Такой категории нет.")
return
children_list_res = get_category_children(terminal_classifier_name)
if children_list_res:
if order == 'прямой':
print(f'дочерние элементы для категории "{terminal_classifier_name}": \n {children_list_res}')
elif order == 'обратный':
print(f'дочерние элементы для категории "{terminal_classifier_name}": \n {children_list_res[::-1]}')
else:
print('Такого порядка вывода нет!')
else:
print(f'У категории "{terminal_classifier_name}" нет дочерних элементов')
def get_category_children(terminal_classifier_name):
if is_category_exists(terminal_classifier_name):
try:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
category_id = cursor.fetchone()[0]
# function for recursive search subcategories
def find_children(category_id, children_list):
childrens_id = 0
childrens_id = []
cursor.execute("SELECT COUNT(*) FROM terminal_classifier WHERE id_parent = ?", (category_id,))
record_exists = cursor.fetchall()
if record_exists:
cursor.execute("SELECT id FROM terminal_classifier WHERE id_parent = ?", (category_id,))
childrens_id = cursor.fetchall()
if childrens_id == 0:
return
if category_id != 0 and childrens_id != 0:
for elem in childrens_id:
elem_id = elem[0]
cursor.execute("SELECT terminal_classifier_name FROM terminal_classifier WHERE id = ?", (elem_id,))
child_name = cursor.fetchone()
children_list.append(child_name)
find_children(elem_id, children_list)
children_list = []
children_list_res = []
# begin search subcategories
find_children(category_id, children_list)
for elem in children_list:
if elem:
children_list_res.append(elem[0])
return children_list_res
except Exception as _ex:
print(f"Произошла ошибка при получении списка дочерних категорий: {_ex}")
else:
print('Категории не существует.')
############### added after first review ###############
def print_products_of_category(terminal_classifier_name, order):
products = get_products_of_category(terminal_classifier_name)
if products:
print(f'Изделия для категории "{terminal_classifier_name}":')
print_str = ''
if order == 'прямой':
for prod in products:
print_str += '"' + prod + '"' + ' '
print(print_str)
elif order == 'обратный':
products = products[::-1]
for prod in products:
print_str += '"' + prod + '"' + ' '
print(print_str)
else:
print('Такого порядка вывода нет!')
else:
print(f'У категории "{terminal_classifier_name}" нет изделий')
def get_products_of_category(terminal_classifier_name):
if is_category_exists(terminal_classifier_name):
try:
categories_to_check = get_category_children(terminal_classifier_name)
products = []
if categories_to_check:
for category in categories_to_check:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (category,))
id_of_searched_category = cursor.fetchone()[0]
cursor.execute("SELECT id FROM product WHERE id_category = ?", (id_of_searched_category,))
products_id = cursor.fetchall()
for id in products_id:
cursor.execute("SELECT product_name FROM product WHERE id = ?", (id[0],))
product_to_add = cursor.fetchone()[0]
products.append(product_to_add)
else:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_of_searched_category = cursor.fetchone()[0]
cursor.execute("SELECT id FROM product WHERE id_category = ?", (id_of_searched_category,))
products_id = cursor.fetchall()
for id in products_id:
cursor.execute("SELECT product_name FROM product WHERE id = ?", (id[0],))
product_to_add = cursor.fetchone()[0]
products.append(product_to_add)
return products
except Exception as _ex:
print(f"Произошла ошибка при поиске изделия заданной категории: {_ex}")
else:
print('Категории не существует.')
##################################### third lab #####################################
def create_param(new_name, new_short_name, new_unit_id, new_min_val, new_max_val):
try:
cursor.execute('''SELECT unit_name FROM unit WHERE id = ?''', (new_unit_id,))
is_unit_exist = cursor.fetchone()
if not is_unit_exist:
print(f'Ошибка в create_param: Единицы измерения не сушествует.')
cursor.execute('''
INSERT INTO param(param_name, param_short_name, unit_id, min_val, max_val)
VALUES (?, ?, ?, ?, ?)
''', (new_name, new_short_name, new_unit_id, new_min_val, new_max_val))
# Проверка количества вставленных строк
if cursor.rowcount == 1:
conn.commit()
print(f'параметр с именем {new_name} успешно добавлен.')
return 1
else:
conn.rollback()
return 0
except sqlite3.Error as e:
# В случае ошибки откатываем транзакцию
print(f"An error occurred in create_param: {e}")
conn.rollback()
return 0
def edit_param(param_id, new_name, new_short_name, new_unit_id, new_min_val, new_max_val):
try:
# Начало транзакции
conn.execute('BEGIN TRANSACTION')
cursor.execute('''SELECT param_name FROM param WHERE id = ? ''', (param_id,))
is_param_exist = cursor.fetchone()
if not is_param_exist:
print(f'Ошибка в edit_param: Параметра с id = {param_id} не существует.')
return 0
cursor.execute('''SELECT unit_name FROM unit WHERE id = ? ''', (new_unit_id,))
is_unit_exist = cursor.fetchone()
if not is_unit_exist:
print(f'Ошибка в edit_param: Единицы измерения с id = {new_unit_id} не существует.')
return 0
# Выполнение запроса на обновление
cursor.execute('''
UPDATE param
SET param_name = ?, param_short_name = ?, unit_id = ?, min_val = ?, max_val = ?
WHERE id = ?
''', (new_name, new_short_name, new_unit_id, new_min_val, new_max_val, param_id))
conn.commit()
# Получение количества обновленных строк
res = cursor.rowcount
# Фиксация изменений
conn.commit()
# Возвращение результата
if res == 1:
print(f'Параметр с id = {param_id} успешно обновлен.')
return 1
else:
return 0
except sqlite3.Error as e:
print(f"Ошибка в edit_param: {e}")
conn.rollback()
return 0
def delete_param(param_to_delete):
cursor.execute('''SELECT id FROM param WHERE param_name = ? ''', (param_to_delete,))
param_id = cursor.fetchone()
if not param_id:
print(f'Ошибка. Параметра с таким названием не существует')
return 0
else:
param_id = param_id[0]
print(f'param_id - {param_id}')
def del_param_from__class_param():
cursor.execute('''SELECT id FROM class_param WHERE param_id = ? ''', (param_id,))
classes_id_to_del = cursor.fetchall()
print(f'classes_id_to_del - {classes_id_to_del}')
for elem_id in classes_id_to_del:
print(f'elem_id - {elem_id[0]}')
cursor.execute("DELETE FROM class_param WHERE id = ?", (elem_id[0],))
conn.commit()
print(f'Классы параметров (если были) удаляемого параметра были обновлены')
del_param_from__class_param()
cursor.execute("DELETE FROM param WHERE param_name = ?", (param_to_delete,))
res = cursor.rowcount
conn.commit()
# Возвращение результата в зависимости от количества удаленных строк
if res == 1:
print(f'Параметр успешно удален.')
return 1
else:
print(f'При удалении параметра что-то пошло не так.')
return 0
def create_class_param(terminal_classifier_name_class, terminal_classifier_name_short_class, param_name, parent_class_param_name=None):
try:
cursor.execute("SELECT id FROM param WHERE param_name = ?", (param_name,))
param_id = cursor.fetchone()
if not param_id:
print(f'Ошибка в create_class_param: параметра с именем {param_name} не существует в таблице param')
return 0
else:
param_id = param_id[0]
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (parent_class_param_name,))
parent_class_id = cursor.fetchone()
if not parent_class_id:
print(f'В create_class_param: для параметра \"{terminal_classifier_name_class}\" класса параметра (родителя) с именем \"{parent_class_param_name}\" не существует в таблице \"terminal_classifier\", будет вставлено значение \"None\"')
parent_class_id = None
else:
parent_class_id = parent_class_id[0]
# Получаем максимальное значение priority для данного class_id
cursor.execute(''' SELECT COUNT(*) FROM class_param WHERE param_class_name = ? ''', (terminal_classifier_name_class,))
res = cursor.fetchone()[0]
if res is None:
res = 0
else:
cursor.execute(''' SELECT MAX(priority) + 1 FROM class_param WHERE param_class_name = ? ''', (terminal_classifier_name_class,))
res = cursor.fetchone()[0]
if res is None:
res = 0
cursor.execute('''SELECT unit_id FROM param WHERE param_name = ? ''', (param_name,))
unit_id = cursor.fetchone()
if not unit_id:
print(f'Единицы измерения с заданным {unit_id} не найдено. Будет вставлено NULL')
else:
unit_id = unit_id[0]
cursor.execute('''
INSERT INTO terminal_classifier(id_parent, terminal_classifier_name, terminal_classifier_short_name, id_unit, priority)
VALUES (?, ?, ?, ?, ?)
''', (parent_class_id, terminal_classifier_name_class, terminal_classifier_name_short_class, unit_id, res))
cursor.execute('''
INSERT INTO class_param(param_class_name, param_class_short_name, class_param_id, param_id, priority)
VALUES (?, ?, ?, ?, ?)
''', (terminal_classifier_name_class, terminal_classifier_name_short_class, parent_class_id, param_id, res))
conn.commit()
except sqlite3.Error as e:
# В случае ошибки откатываем транзакцию
print(f"An error occurred: {e}")
conn.rollback()
return 0
def edit_class_param(id, new_param_class_name, new_param_class_short_name, new_param_id=None, class_param_id=None):
try:
# Начало транзакции
conn.execute('BEGIN TRANSACTION')
cursor.execute('''SELECT param_class_name FROM class_param WHERE id = ? ''', (id,))
is_class_param_exist = cursor.fetchone()
if not is_class_param_exist:
print(f'Ошибка в edit_class_param: Параметра класса с id = {id} не существует.')
return 0
else:
param_class_name_old = is_class_param_exist[0]
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', (param_class_name_old,))
id_class_param_in_tc = cursor.fetchone()[0]
if new_param_id:
cursor.execute('''SELECT param_name FROM param WHERE id = ? ''', (new_param_id,))
is_param_exist = cursor.fetchone()
if not is_param_exist:
print(f'Ошибка в edit_class_param: Параметра с id = {new_param_id} не существует.')
return 0
else:
cursor.execute('''SELECT id FROM param WHERE param_name = ? ''', ('неопределенный параметр',))
new_param_id = cursor.fetchone()[0]
if class_param_id:
cursor.execute('''SELECT terminal_classifier_name FROM terminal_classifier WHERE id = ? ''', (class_param_id,))
is_terminal_class_name_exist = cursor.fetchone()
if check_cyclic_dependency_terminal_classifier(class_param_id, param_class_name_old):
print("Ошибка в edit_class_param: родитель и потомок образуют цикл. ")
return 0
if (is_terminal_class_name_exist[0] == param_class_name_old):
print(f'_terminal_class_name_ = {is_terminal_class_name_exist[0]}, param_class_name_old = {param_class_name_old} =>', sep='')
print(f'Нельзя назначить классу в родителя самого себя')
return 0
if not is_terminal_class_name_exist:
print(f'Ошибка в edit_class_param: Параметра класса с id = {id} не существует.')
return 0
if change_parent_of_category(param_class_name_old, is_terminal_class_name_exist[0]):
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', ('неопределенный параметр класса',))
class_param_id = cursor.fetchone()[0]
cursor.execute("UPDATE class_param SET param_class_name = ?, param_class_short_name = ?, param_id = ?, class_param_id = ? WHERE id = ?", (new_param_class_name, new_param_class_short_name, new_param_id, class_param_id, id))
cursor.execute("UPDATE terminal_classifier SET terminal_classifier_name = ?, terminal_classifier_short_name = ?, id_parent = ? WHERE id = ?", (new_param_class_name, new_param_class_short_name, class_param_id, id_class_param_in_tc))
res = cursor.rowcount
# Фиксация изменений
conn.commit()
# Возвращение результата
if res == 1:
print(f'Параметр с id = {id} успешно обновлен.')
return 1
else:
return 0
else:
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', ('неопределенный параметр класса',))
class_param_id = cursor.fetchone()[0]
cursor.execute("UPDATE class_param SET param_class_name = ?, param_class_short_name = ?, param_id = ?, class_param_id = ? WHERE id = ?", (new_param_class_name, new_param_class_short_name, new_param_id, class_param_id, id))
cursor.execute("UPDATE terminal_classifier SET terminal_classifier_name = ?, terminal_classifier_short_name = ?, id_parent = ? WHERE id = ?", (new_param_class_name, new_param_class_short_name, class_param_id, id_class_param_in_tc))
res = cursor.rowcount
# Фиксация изменений
conn.commit()
# Возвращение результата
if res == 1:
print(f'Параметр класса с id = {id} успешно обновлен.')
return 1
else:
return 0
except sqlite3.Error as e:
print(f"Ошибка в edit_class_param: {e}")
conn.rollback()
return 0
def delete_class_param(class_to_delete):
try:
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', (class_to_delete,))
exists = cursor.fetchone()
if not exists:
print(f'Ошибка в delete_class_param: Класса параметра с таким названием не существует')
return 0
if (class_to_delete == 'неопределенный параметр класса' or class_to_delete == 'параметр класса'):
print(f"Нельзя удалить параметр класса \'неопределенный параметр класса\' или \'параметр класса\'")
return 0
# Проверка на наличие дочерних элементов
is_children_exist = get_category_children(class_to_delete)
print(f'is_children_exist - {is_children_exist}')
if not is_children_exist:
cursor.execute("DELETE FROM class_param WHERE param_class_name = ?", (class_to_delete,))
conn.commit()
cursor.execute("DELETE FROM terminal_classifier WHERE terminal_classifier_name = ?", (class_to_delete,))
conn.commit()
else:
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', (class_to_delete,))
id_class_to_delete = cursor.fetchone()[0]
print(f'class_to_delete - {class_to_delete}')
print(f'id_class_to_delete - {id_class_to_delete}')
cursor.execute("SELECT id FROM class_param WHERE class_param_id = ? ", (id_class_to_delete,))
children = cursor.fetchall()
print(f'children (id) - {children}')
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', ('неопределенный параметр класса',))
undef_class_id = cursor.fetchone()[0]
children_info_rows = []
for child in children:
print(f'child - {child}')
cursor.execute('''SELECT param_class_name FROM class_param WHERE id = ? ''', (child[0],))
child_name = cursor.fetchone()[0]
print(f'child_name - {child_name}')
cursor.execute('''SELECT * FROM class_param WHERE id = ?''', (child[0],))
child_row = cursor.fetchone()[0]
children_info_rows.append(child_row)
cursor.execute("UPDATE class_param SET class_param_id = ? WHERE id = ?", (undef_class_id, child[0]))
change_parent_of_terminal_classifier(child_name, 'неопределенный параметр класса')
conn.commit()
cursor.execute("DELETE FROM class_param WHERE param_class_name = ?", (class_to_delete,))
conn.commit()
cursor.execute("DELETE FROM terminal_classifier WHERE terminal_classifier_name = ?", (class_to_delete,))
conn.commit()
print(f'children_info_rows - {children_info_rows}')
conn.commit()
print("Удаление завершено успешно")
return 1
except sqlite3.IntegrityError as e:
print(f"Ошибка в delete_class_param: {e}")
conn.rollback()
return 0
def inherit_class_parameters(new_class_to_inherit__name, new_class_to_inherit__short_name, parent_class__name):
try:
# Получаем parent_id
cursor.execute('''
SELECT id FROM class_param WHERE param_class_name = ?
''', (parent_class__name,))
parent_id_row = cursor.fetchone()
if parent_id_row is None:
print(f'Ошибка в inherit_class_parameters: класса параметра с именем для наследования не найдено')
return 0 # Если id родителя в таблице class_param не найдено
# Получаем параметры из CLASS_PARAM для parent_id
cursor.execute('''
SELECT class_param_id, param_id FROM class_param WHERE param_class_name = ? ORDER BY priority
''', (parent_class__name,))
param_rows = cursor.fetchall()
print(f'param_rows - {param_rows}')
for param_row in param_rows:
class_param_id, param_id = param_row
# Проверяем, существует ли уже параметр для данного cl_id
cursor.execute('''
SELECT 1 FROM class_param WHERE param_class_name = ? AND param_id = ?
''', (new_class_to_inherit__name, param_id))
exists = cursor.fetchone()
cursor.execute('''
SELECT param_name FROM param WHERE id = ?''', (param_id,))
param_name = cursor.fetchone()[0]
print(f'exists ? - {exists}')
if exists:
print(f'Класс параметра с именем {new_class_to_inherit__name} уже существует.')
if not exists:
create_class_param(new_class_to_inherit__name, new_class_to_inherit__short_name, param_name, parent_class__name)
conn.commit()
except sqlite3.Error as e:
print(f"An error occurred in inherit_class_parameters: {e}")
conn.rollback()
return 0
def edit_class_param_output_priority(class_id, id, priority):
try:
# Выполнение запроса для получения количества записей с указанным priority и id класса
cursor.execute("""
SELECT count(*)
FROM class_param
WHERE priority = ? AND class_param_id = ?
""", (priority, class_id))
# Получение результата запроса
cnt = cursor.fetchone()[0]
if cnt == 0:
# Если таких записей нет, обновляем priority для указанной записи
cursor.execute("""
UPDATE class_param
SET priority = ?
WHERE class_param_id = ? AND id = ?
""", (priority, class_id, id))
else:
# Если такие записи есть, увеличиваем output_priority для всех записей с priority >= переданного в функцию priority
cursor.execute("""
UPDATE class_param
SET priority = priority + 1
WHERE priority >= ? AND class_param_id = ?
""", (priority, class_id))
# Затем обновляем priority для указанной записи
cursor.execute("""
UPDATE class_param
SET priority = ?
WHERE class_param_id = ? AND id = ?
""", (priority, class_id, id))
conn.commit()
print(f'Приоритет изменен.')
return priority
except sqlite3.Error as e:
print(f"An error occurred in edit_class_param_output_priority: {e}")
conn.rollback()
return 0
def is_param_allowed_to_prod_category(param_id, prod_id):
try:
if not (is_exist_by_id_in_table(param_id, PARAM_TABLE)):
raise ValueError(f'параметра с id={param_id} не существует в таблице {PARAM_TABLE}')
if not (is_exist_by_id_in_table(prod_id, PRODUCT_TABLE)):
raise ValueError(f'продукции с id={prod_id} не существует в таблице {PRODUCT_TABLE}')
cursor.execute("SELECT id_category FROM product WHERE id = ?", (prod_id,))
product_id_category = cursor.fetchone()
if product_id_category:
product_id_category = product_id_category[0]
print(f'- - product_id_category - {product_id_category}')
cursor.execute("SELECT id FROM class_param WHERE param_id = ? AND class_param_id = ?", (param_id, product_id_category))
class_param_id_row = cursor.fetchone()
# print(f'- - class_param_id_row - {class_param_id_row}')
if class_param_id_row:
return True
else:
return False
except sqlite3.Error as e:
print(f"An error occurred in is_param_allowed_to_prod: {e}")
conn.rollback()
return 0
def create_prod_param(new_prod_id, new_param_id, is_configurable):
try:
cursor.execute("SELECT product_name FROM product WHERE id = ?", (new_prod_id,))
is_new_product_name_exist = cursor.fetchone()
if is_new_product_name_exist is None:
print(f'Ошибка в create_prod_param: изделия с id {new_prod_id} не найдено')
return 0
cursor.execute('''
SELECT param_name FROM param WHERE id = ?
''', (new_param_id,))
is_new_param_name_exist = cursor.fetchone()
if is_new_param_name_exist is None:
print(f'Ошибка в create_prod_param: параметра с id {new_param_id} не найдено')
return 0
# проверяем, является ли изделие вариантом исполнения
cursor.execute('''
SELECT configurable_type FROM product WHERE id = ?
''', (new_prod_id,))
configurable_type = cursor.fetchone()[0]
if configurable_type == 0:
raise ValueError(f'Вы пытаетесь задать значения параметров обычному изделию с типом 0, которое не может быть параметризовано. Вместо этого, сначала сделайте конфигурацию для этой продукции через функцию create_configuration_product_by_existing_prod_id')
# 2-3 lab check
if not (is_param_allowed_to_prod_category(new_param_id, new_prod_id)):
raise ValueError(f'ошибка! для продукции с id={new_prod_id} параметр с id={new_param_id} является недопустимым. \nЕсли параметр должен быть допустимым, добавьте запись в таблицу class_param с id параметра из таблицы param и class_param_id(id_category в таблице terminal_classifier) для продукции соотвествующей category')
# 2-3 lab check
if not (isinstance(is_configurable, bool)):
raise ValueError(f'значения переданного аргумента is_configurable={is_configurable} не является bool')
cursor.execute('''
INSERT INTO prod_param (prod_id, param_id, is_configurable)
VALUES (?, ?, ?)
''', (new_prod_id, new_param_id, is_configurable))
res = cursor.rowcount
conn.commit()
if res == 1:
print(f'\nДобавлена запись в таблицу prod_param\n')
return 1
else:
return 0
except sqlite3.Error as e:
print(f"Ошибка в create_prod_param: {e}")
conn.rollback()
return 0
def fill_prod_param(prod_id, param_id, new_int_val, new_real_val, new_str_val):
try:
# Validate product and parameter existence
if not is_exist_by_id_in_table(prod_id, PRODUCT_TABLE):
raise ValueError(f'нет продукта с таким prod_id={prod_id} в таблице product')
if not is_exist_by_id_in_table(param_id, PARAM_TABLE):
raise ValueError(f'нет параметра с таким param_id={param_id} в таблице param')
cursor.execute('''
SELECT configurable_type FROM product WHERE id = ?
''', (prod_id,))
configurable_type = cursor.fetchone()[0]
if configurable_type in [0, 1]:
variant = ''
if configurable_type == 0:
variant = 'продукция без конфигуратора'
if configurable_type == 1:
variant = 'продукция с конфигуратора'
raise ValueError(f'ошибка! заполнение параметров для продукции доступно только для варианта исполнения. тип введеного id продукции = {variant}')
# Validate new_int_val range
if new_int_val is not None:
cursor.execute('''SELECT min_val, max_val FROM param WHERE id = ?''', (param_id,))
min_val, max_val = cursor.fetchone()
if not (min_val <= new_int_val <= max_val):
raise ValueError(f'значение {new_int_val} не попадает в промежуток границ параметра [{min_val} ; {max_val}]')
# Validate new_real_val range
if new_real_val is not None:
cursor.execute('''SELECT min_val, max_val FROM param WHERE id = ?''', (param_id,))
min_val, max_val = cursor.fetchone()
if not (min_val <= new_real_val <= max_val):
raise ValueError(f'значение {new_real_val} не попадает в промежуток границ параметра [{min_val} ; {max_val}]')
# Проверка существования записи
cursor.execute('''
SELECT COUNT(*) FROM prod_param WHERE prod_id = ? AND param_id = ?
''', (prod_id, param_id))
exists = cursor.fetchone()[0]
if exists:
# Обновление существующей записи
cursor.execute('''
UPDATE prod_param
SET int_value = ?, str_value = ?, real_value = ?
WHERE prod_id = ? AND param_id = ?
''', (new_int_val, new_str_val, new_real_val, prod_id, param_id))
else:
# Добавление новой записи
cursor.execute('''
INSERT INTO prod_param (prod_id, param_id, int_value, str_value, real_value)
VALUES (?, ?, ?, ?, ?)
''', (prod_id, param_id, new_int_val, new_str_val, new_real_val))
# Проверка успешности операции
cursor.execute('''
SELECT int_value, str_value, real_value
FROM prod_param
WHERE prod_id = ? AND param_id = ?
''', (prod_id, param_id))
updated_row = cursor.fetchone()
if (updated_row == (new_int_val, new_str_val, new_real_val)):
print(f'для изделия с prod_id={prod_id} обновлены или добавлены параметры с param_id={param_id}')
conn.commit()
return 1
else:
raise ValueError(f'не получилось вставить или обновить значения параметра с param_id={param_id} для изделия с prod_id={prod_id}')
except sqlite3.Error as e:
print(f"Ошибка в fill_prod_param: {e}")
conn.rollback()
return 0
# вроде не очень
def edit_prod_param(id, new_int_val, new_str_val, new_real_val, new_enum_val):
try:
# Начало транзакции
conn.execute('BEGIN TRANSACTION')
new_enum_val
# проверка на существование new_enum_val
cursor.execute('''
SELECT id FROM enum WHERE enum_name = ?
''', (new_enum_val,))
is_enum_exist = cursor.fetchall()
print(f'is_enum_exist - {is_enum_exist}')
if is_enum_exist is None:
print(f'Ошибка в edit_prod_param: записи с new_enum_val {new_enum_val} в enum не найдено')
return 0
else:
new_enum_id = is_enum_exist[0]
# проверка на существование id
cursor.execute('''
SELECT prod_id, param_id FROM prod_param WHERE id = ?
''', (id,))
is_id_exist = cursor.fetchall()
print(f'is_id_exist - {is_id_exist}')
if is_id_exist is None:
print(f'Ошибка в edit_prod_param: записи с id {id} в prod_param не найдено')
return 0
print(f'enum_id - {new_enum_id[0]}')
# Выполнение запроса на обновление данных
cursor.execute('''
UPDATE prod_param
SET int_value = ?, str_value = ?, enum_id = ?, real_value = ?
WHERE id = ?
''', (new_int_val, new_str_val, new_enum_id[0], new_real_val, id))
# Получение количества обновленных строк
res = cursor.rowcount
# Фиксация изменений
conn.commit()
# Возвращение результата
if res == 1:
return 1
else:
return 0
except sqlite3.Error as e:
print(f"Ошибка в edit_prod_param: {e}")
conn.rollback()
return 0
def find_param_id_from_prod(prod_id):
try:
cursor.execute('SELECT product_name FROM product WHERE id = ?', (prod_id,))
product_name = cursor.fetchone()
if product_name:
product_name = product_name[0]
else:
print(f'изделия с id - {prod_id} не существует.')
return 0
# Начало транзакции
conn.execute('BEGIN TRANSACTION')
# Получение class_id из таблицы obj
cursor.execute('SELECT id_category FROM product WHERE id = ?', (prod_id,))
id_parent = cursor.fetchone()
print(f'id_parent = {id_parent}')
if id_parent is None:
print(f'Ошибка: объект с id {prod_id} не найден')
return []
id_parent = id_parent[0]
# Получение param_id из таблицы class_param, упорядоченных по output_priority
cursor.execute('''
SELECT param_id FROM class_param
WHERE class_param_id = ?
ORDER BY priority
''', (id_parent,))
param_ids = cursor.fetchall()
# Фиксация изменений
conn.commit()
# Возвращение результата в виде списка
return [row[0] for row in param_ids]
except sqlite3.Error as e:
print(f"Ошибка в find_param_id_from_prod: {e}")
conn.rollback()
return []
def find_products_of_class_param(id_of_class_param_el):
cursor.execute('SELECT param_class_name FROM class_param WHERE id = ?', (id_of_class_param_el,))
name_of_class_param_el = cursor.fetchone()
print(f'id_of_class_param_el - {name_of_class_param_el}')
if name_of_class_param_el:
name_of_class_param_el = name_of_class_param_el[0]
else:
print(f'класса параметра с названием - {name_of_class_param_el} не существует.')
return 0
cursor.execute('SELECT class_param_id FROM class_param WHERE id = ?', (id_of_class_param_el,))
class_param_id = cursor.fetchone()
print(f'name_of_class_param_el - {name_of_class_param_el}')
if class_param_id:
class_param_id = class_param_id[0]
else:
print(f'класс параметра с id категории изделий - {class_param_id} не существует.')
return 0
cursor.execute('SELECT * FROM product WHERE id_category = ?', (class_param_id,))
products = cursor.fetchall()
if products:
products = products[0]
else:
print(f'изделия с id классом параметра - {class_param_id} не существует.')
return 0
return products
def find_products_in_interval_param(param_id, type_value, start_val, end_val):
if 'int' in type_value.lower():
cursor.execute('SELECT prod_id FROM prod_param WHERE param_id = ? AND int_value >= ? AND int_value <= ?', (param_id, start_val, end_val))
prod_ids = cursor.fetchall()
if prod_ids:
prod_ids = prod_ids
return prod_ids
else:
print(f'изделий с param_id = {param_id}, type_value = {type_value}, start_val = {start_val}, end_val = {end_val} нет в таблице product')
return
if 'real' in type_value.lower():
cursor.execute('SELECT prod_id FROM prod_param WHERE param_id = ? AND real_value >= ? AND real_value <= ?', (param_id, start_val, end_val))
prod_ids = cursor.fetchall()
if prod_ids:
prod_ids = prod_ids
return prod_ids
else:
print(f'изделий с param_id = {param_id}, type_value = {type_value}, start_val = {start_val}, end_val = {end_val} нет в таблице product')
return
##################################### third lab #####################################
##################################### 2-1 lab #####################################
def create_acceptable_component(new_class_id, new_component_id):
# Prevent self-referencing components
if new_class_id == new_component_id:
print("Error: нельзя создать цикл с одинаковыми class_id и component_id!")
return 0 # Failure
try:
# Recursive query to check for cycles in acceptable_components
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 cursor.fetchone():
print(f"Error: добавление пары ({new_class_id}, {new_component_id}) создаёт цикл!")
return 0 # Failure
# Insert the new relationship if no cycle is detected
cursor.execute('''
INSERT INTO acceptable_components (class_id, component_id)
VALUES (?, ?)
''', (new_class_id, new_component_id))
conn.commit()
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
# cycle checking
def check_cyclic_dependency_specif(new_class_id, comp_id):
def fetch_parent_category(cat_id):
cursor.execute("SELECT prod_id FROM prod_position_union WHERE comp_id = ?", (cat_id,))
return cursor.fetchone()[0]
current_id = new_class_id
while current_id is not None:
if current_id == comp_id:
return True
current_id = fetch_parent_category(current_id)
return False
# ???
def create_prod_position_union(new_object_id, new_component_id, new_quantity):
try:
cursor.execute('SELECT id_category FROM product WHERE id = ?', (new_object_id,))
obj_class_id = cursor.fetchone()
if obj_class_id is None:
raise ValueError("Object ID not found")
cursor.execute('SELECT id_category FROM product WHERE id = ?', (new_component_id,))
comp_class_id = cursor.fetchone()
if comp_class_id is None:
raise ValueError("Component ID not found")
cursor.execute('''
SELECT 1
FROM acceptable_components
WHERE class_id = ? AND component_id = ?
''', (obj_class_id[0], comp_class_id[0]))
if cursor.fetchone() is None:
raise ValueError("Invalid composition for the object!")
cursor.execute('''
INSERT INTO prod_position_union (prod_id, comp_id, quantity)
VALUES (?, ?, ?)
''', (new_object_id, new_component_id, new_quantity))
conn.commit()
print('таблица prod_position_union успешно обновлена новым значением.')
return 1 # Success
except Exception as e:
print(f"Error: {e}")
return 0 # Failure
def is_prod_position_union(prod_id, comp_id):
cursor.execute('SELECT 1 FROM prod_position_union WHERE prod_id = ? AND comp_id =?', (prod_id, comp_id,))
res = cursor.fetchone()
if res:
return True
else:
return False
def delete_prod_position_union(prod_id, comp_id):
cursor.execute('''
DELETE FROM prod_position_union
WHERE prod_id = ? AND comp_id = ?
''', (prod_id, comp_id))
deleted_rows = cursor.rowcount
conn.commit()
print(f'в таблице prod_position_union успешно удалено значение - {prod_id, comp_id}')
return 1 if deleted_rows == 1 else 0
def delete_acceptable_component(cl_id, component_cl_id):
deleted_count = 0
try:
# Fetch all products linked to the class_id and component_id
cursor.execute('SELECT id FROM product WHERE id_category = ?', (cl_id,))
obj_ids = [row[0] for row in cursor.fetchall()]
cursor.execute('SELECT id FROM product WHERE id_category = ?', (component_cl_id,))
comp_ids = [row[0] for row in cursor.fetchall()]
# Delete all associated position compositions
for obj_id in obj_ids:
for comp_id in comp_ids:
if is_prod_position_union(obj_id, comp_id):
deleted_count += delete_prod_position_union(obj_id, comp_id)
# Fetch all parents of the component_cl_id (nodes where component_cl_id is a child)
cursor.execute('''
SELECT class_id FROM acceptable_components
WHERE component_id = ?
''', (cl_id,))
parents = [row[0] for row in cursor.fetchall()]
# Fetch all children of the component_cl_id (nodes where component_cl_id is a parent)
cursor.execute('''
SELECT component_id FROM acceptable_components
WHERE class_id = ?
''', (component_cl_id,))
children = [row[0] for row in cursor.fetchall()]
# Delete the specified relationship
cursor.execute('''
DELETE FROM acceptable_components
WHERE class_id = ? AND component_id = ?
''', (cl_id, component_cl_id))
# Connect parents of cl_id to children of component_cl_id
for parent in parents:
for child in children:
# Check if the relationship already exists
cursor.execute('''
SELECT 1 FROM acceptable_components
WHERE class_id = ? AND component_id = ?
''', (parent, child))
if cursor.fetchone() is None:
cursor.execute('''
INSERT INTO acceptable_components (class_id, component_id)
VALUES (?, ?)
''', (parent, child))
conn.commit()
print(f'из класса с id - {cl_id} успешно удален компонент с id - {component_cl_id}, соединены родители и дети.')
return deleted_count
except Exception as e:
print(f"Error: {e}")
return deleted_count
def edit_prod_position_union_quantity(obj_id, comp_id, new_quantity):
cursor.execute('''
UPDATE prod_position_union
SET quantity = ?
WHERE prod_id = ? AND comp_id = ?
''', (new_quantity, obj_id, comp_id))
updated_rows = cursor.rowcount
conn.commit()
print(f"значение позиции {(obj_id, comp_id)} установлено в {new_quantity}")
return 1 if updated_rows == 1 else 0
def inherit_acceptable_components(cl_id):
inserted_count = 0
try:
cursor.execute('SELECT id_parent FROM terminal_classifier WHERE id = ?', (cl_id,))
parent_cl_id = cursor.fetchone()
if parent_cl_id is None:
raise ValueError("Parent class ID not found")
cursor.execute('''
SELECT component_id FROM acceptable_components
WHERE class_id = ?
''', (parent_cl_id[0],))
components = cursor.fetchall()
# Insert acceptable components for the child class
for (component_id,) in components:
cursor.execute('''
INSERT OR IGNORE INTO acceptable_components (class_id, component_id)
VALUES (?, ?)
import sqlite3
path = "C:/Users/admin/source/repos/UNIVERSITY_repos/4 course/7 sem/mispris/2-4/furniture.db"
# path = "/home/user/repos/mispris/3/furniture.db"
conn = sqlite3.connect(path)
cursor = conn.cursor()
conn.execute("PRAGMA foreign_keys = ON")
print("\n\nDB has been created/connected\n")
ACCEPTABLE_COMPONENTS_TABLE = 'acceptable_components'
CLASS_PARAM_TABLE = 'class_param'
ENUM_TABLE = 'enum'
INPUT_RESOURCES_TABLE = 'input_resources'
PARAM_TABLE = 'param'
PROD_OPERATION_TABLE = 'prod_operation'
PROD_PARAM_TABLE = 'prod_param'
PROD_POSITION_UNION_TABLE = 'prod_position_union'
PRODUCT_TABLE = 'product'
TERMINAL_CLASSIFIER_TABLE = 'terminal_classifier'
UNIT_TABLE = 'unit'
FUNC_TABLE = 'func'
PREDICATE_TABLE = 'predicate'
FUNC_BODY_TABLE = 'func_body'
PROD_SPEC_TABLE = 'prod_spec'
ENUM_OPERATORS_CLASS_NAME = 'перечисление операторов'
ENUM_PARAMS_VALUE = 'перечисление значений параметров'
def create_unit_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS unit (
id INTEGER PRIMARY KEY AUTOINCREMENT,
unit_name TEXT UNIQUE,
unit_name_short TEXT UNIQUE
)
''')
conn.commit()
def create_terminal_classifier_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS terminal_classifier (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id_parent INTEGER CHECK (id_parent != id),
terminal_classifier_name TEXT NOT NULL,
terminal_classifier_short_name TEXT NOT NULL,
id_unit INTEGER,
priority INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (id_unit) REFERENCES unit(id) ON DELETE CASCADE,
FOREIGN KEY (id_parent) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_enum_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS enum (
id INTEGER PRIMARY KEY AUTOINCREMENT,
enum_id INTEGER,
enum_name TEXT NOT NULL,
enum_short_name TEXT NOT NULL,
enum_description TEXT,
real_value REAL,
int_value INTEGER,
str_value TEXT,
priority INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (enum_id) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_product_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS product (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id_category INTEGER,
configurable_type INTEGER NOT NULL DEFAULT 0,
product_name_short TEXT,
product_name TEXT NOT NULL,
quantity INTEGER,
price REAL,
unit_value REAL,
place INTEGER,
FOREIGN KEY (id_category) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_param_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS param (
id INTEGER PRIMARY KEY AUTOINCREMENT,
param_name TEXT NOT NULL,
param_short_name TEXT NOT NULL,
unit_id INTEGER,
min_val REAL,
max_val REAL,
FOREIGN KEY (unit_id) REFERENCES unit(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_class_param_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS class_param (
id INTEGER PRIMARY KEY AUTOINCREMENT,
param_id INTEGER NOT NULL,
class_param_id INTEGER,
param_class_name TEXT NOT NULL,
param_class_short_name TEXT NOT NULL,
priority INTEGER NOT NULL,
FOREIGN KEY (param_id) REFERENCES param(id) ON DELETE CASCADE,
FOREIGN KEY (class_param_id) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
##################################### modified due to 2-3 lab
def create_prod_param_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS prod_param (
id INTEGER PRIMARY KEY AUTOINCREMENT,
prod_id INTEGER NOT NULL,
param_id INTEGER NOT NULL,
is_configurable BOOLEAN NOT NULL DEFAULT FALSE,
int_value INTEGER,
str_value TEXT,
real_value REAL,
enum_value TEXT,
class_value INTEGER,
UNIQUE (prod_id, param_id),
FOREIGN KEY (param_id) REFERENCES param(id) ON DELETE CASCADE,
FOREIGN KEY (prod_id) REFERENCES product(id) ON DELETE CASCADE
)
''')
conn.commit()
##################################### modified due to 2-3 lab
##################################### 2-1 lab #####################################
def create_acceptable_components_table():
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 terminal_classifier(id) ON DELETE CASCADE,
FOREIGN KEY (component_id) REFERENCES terminal_classifier(id) ON DELETE CASCADE
)
''')
conn.commit()
def create_prod_position_union_table():
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
)
''')
conn.commit()
##################################### 2-1 lab #####################################
##################################### 2-2 lab #####################################
def create_prod_operation_table():
cursor.execute('''
CREATE TABLE IF NOT EXISTS prod_operation (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id_operation_type INTEGER NOT NULL,
operation_name TEXT NOT NULL,
operation_priority REAL NOT NULL,
id_shd INTEGER NOT NULL,
prod_id INTEGER NOT NULL,
grc_id INTEGER NOT NULL,
prof_id INTEGER NOT NULL,
prof_qual_id INTEGER,
launch_time REAL NOT NULL,
time_per_obj REAL NOT NULL,
time_unit_id INTEGER NOT NULL,
FOREIGN KEY (id_shd) REFERENCES terminal_classifier(id) ON DELETE CASCADE,
FOREIGN KEY (prod_id) REFERENCES product(id) ON DELETE CASCADE,
FOREIGN KEY (grc_id) REFERENCES terminal_classifier(id) ON DELETE RESTRICT,
FOREIGN KEY (prof_id) REFERENCES terminal_classifier(id) ON DELETE RESTRICT,
FOREIGN KEY (prof_qual_id) REFERENCES enum(id) ON DELETE RESTRICT,
FOREIGN KEY (time_unit_id) REFERENCES unit(id) ON DELETE RESTRICT
);
''')
conn.commit()
def create_input_resources_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS input_resources (
id INTEGER PRIMARY KEY AUTOINCREMENT,
operation_id INTEGER NOT NULL,
prod_id INTEGER NOT NULL,
resource_name TEXT NOT NULL,
unit_id INTEGER NOT NULL,
quantity REAL NOT NULL,
FOREIGN KEY (operation_id) REFERENCES prod_operation(id) ON DELETE CASCADE,
FOREIGN KEY (prod_id) REFERENCES product(id) ON DELETE RESTRICT
FOREIGN KEY (unit_id) REFERENCES unit(id) ON DELETE RESTRICT
);
""")
conn.commit()
##################################### 2-2 lab #####################################
##################################### 2-3 lab #####################################
def create_orders_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer INTEGER NOT NULL,
contact_person INTEGER,
order_time TEXT NOT NULL,
order_completion_time TEXT,
FOREIGN KEY (customer) REFERENCES terminal_classifier(id),
FOREIGN KEY (contact_person) REFERENCES product(id)
);
""")
conn.commit()
def create_orders_pos_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS orders_pos (
order_id INTEGER NOT NULL,
prod_id INTEGER NOT NULL,
quantity INTEGER NOT NULL,
PRIMARY KEY (order_id, prod_id),
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (prod_id) REFERENCES product(id)
);
""")
conn.commit()
##################################### 2-3 lab #####################################
##################################### 2-4 lab #####################################
def create_func_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS func (
id INTEGER PRIMARY KEY AUTOINCREMENT,
class_id INTEGER NOT NULL,
name TEXT NOT NULL,
FOREIGN KEY (class_id) REFERENCES terminal_classifier(id) ON UPDATE CASCADE ON DELETE CASCADE
);
""")
conn.commit()
## замечания, касательно различий реализации:
# у Владоса есть таблица ENUM_POS, у меня, видимо, это просто таблица enum, а сами классы для enum заданы в таблице terminal_classifier
def create_predicate_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS predicate (
id INTEGER PRIMARY KEY AUTOINCREMENT,
operator_id INTEGER NOT NULL,
param_id INTEGER NOT NULL,
enum_pos_id INTEGER NOT NULL,
FOREIGN KEY (param_id) REFERENCES param(id) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (enum_pos_id) REFERENCES enum(id) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (operator_id) REFERENCES enum(id) ON UPDATE CASCADE ON DELETE RESTRICT
);
""")
conn.commit()
def create_func_body_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS func_body (
func_id INTEGER NOT NULL,
conjunction_num INTEGER NOT NULL CHECK (conjunction_num >= 0),
predicate_id INTEGER NOT NULL,
inversio BOOLEAN NOT NULL DEFAULT FALSE,
PRIMARY KEY (func_id, conjunction_num, predicate_id),
FOREIGN KEY (func_id) REFERENCES func(id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (predicate_id) REFERENCES predicate(id) ON UPDATE CASCADE ON DELETE RESTRICT
);
""")
conn.commit()
def create_prod_spec_table():
cursor.execute("""
CREATE TABLE IF NOT EXISTS prod_spec (
prod_id INTEGER NOT NULL,
func_id INTEGER NOT NULL,
PRIMARY KEY (prod_id, func_id),
FOREIGN KEY (func_id) REFERENCES func(id) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (prod_id) REFERENCES product(id) ON UPDATE CASCADE ON DELETE CASCADE
);
""")
conn.commit()
##################################### 2-4 lab #####################################
def creating_tables():
create_unit_table()
create_terminal_classifier_table()
create_enum_table()
create_product_table()
create_param_table()
create_class_param_table()
create_prod_param_table()
#2-1 lab#
create_acceptable_components_table()
create_prod_position_union_table()
#2-1 lab#
#2-2 lab#
create_prod_operation_table()
create_input_resources_table()
#2-2 lab#
#2-3 lab#
create_orders_table()
create_orders_pos_table()
#2-3 lab#
#2-4 lab#
create_func_table()
create_predicate_table()
create_func_body_table()
create_prod_spec_table()
#2-4 lab#
creating_tables()
def delete_data(tables_order):
try:
cursor.execute("PRAGMA foreign_keys = OFF;") # Disable foreign key checks
for table_name in tables_order:
cursor.execute(f"DELETE FROM {table_name};")
conn.commit()
cursor.execute("PRAGMA foreign_keys = ON;") # Re-enable foreign key checks
except sqlite3.Error as ex:
print(f"Произошла ошибка при удалении данных: {ex}")
conn.rollback()
def dropAllTables():
try:
cursor.execute("PRAGMA foreign_keys = OFF;") # Temporarily disable FK constraints
# List all tables in dependency order (most dependent first)
tables_order = [
'prod_spec', # Depends on 'func' and 'product'
'func_body', # Depends on 'func' and 'predicate'
'predicate', # Depends on 'param' and 'enum'
'func', # Depends on 'terminal_classifier'
'orders_pos', # Depends on 'orders' and 'product'
'input_resources', # Child of 'prod_operation' and 'product'
'prod_operation', # Child of 'product', 'unit', etc.
'prod_param', # Child of 'product', 'param', 'enum'
'orders', # Depends on 'product'
'acceptable_components',# Child of 'terminal_classifier'
'prod_position_union', # Child of 'product'
'product', # Child of 'terminal_classifier'
'enum', # Child of 'terminal_classifier'
'class_param', # Child of 'param', 'terminal_classifier'
'param', # Child of 'unit'
'terminal_classifier', # Child of 'unit'
'unit' # No dependencies
]
# Check and drop each table only if it exists
for table_name in tables_order:
cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}'")
if cursor.fetchone(): # Drop only if the table exists
cursor.execute(f"DROP TABLE IF EXISTS {table_name};")
conn.commit()
cursor.execute("PRAGMA foreign_keys = ON;") # Re-enable FK constraints
print("Все таблицы успешно удалены.")
except sqlite3.Error as ex:
print(f"Произошла ошибка при удалении таблиц: {ex}")
conn.rollback()
def is_category_exists(terminal_classifier_name):
cursor.execute("SELECT COUNT(*) FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
count = cursor.fetchone()[0]
res = count > 0
return res
def is_category_id_exists(cl_id):
cursor.execute("SELECT COUNT(*) FROM terminal_classifier WHERE id = ?", (cl_id,))
count = cursor.fetchone()[0]
res = count > 0
return res
def is_product_exist(product_name):
cursor.execute("SELECT COUNT(*) FROM product WHERE product_name = ?", (product_name,))
count = cursor.fetchone()[0]
res = count > 0
return res
def is_unit_exist(unit_name_short):
cursor.execute("SELECT COUNT(*) FROM unit WHERE unit_name_short = ?", (unit_name_short,))
count = cursor.fetchone()[0]
res = count > 0
return res
def add_unit(unit_name, unit_name_short):
try:
if not is_unit_exist(unit_name_short):
cursor.execute('''
INSERT INTO unit (unit_name, unit_name_short)
VALUES (?, ?)
''', (unit_name, unit_name_short))
conn.commit()
print('Единица измерения успешно добавлена.')
else:
print('Единица измерения с таким названием уже существует.')
except Exception as _ex:
print(f'Error {_ex} - произошла ошибка при добавлении единицы измерения')
def add_category(terminal_classifier_name, terminal_classifier_short_name, id_parent=None, id_unit=None):
try:
if is_category_exists(terminal_classifier_name):
raise ValueError(f'Категория с названием {terminal_classifier_name} уже существует.')
if id_unit:
cursor.execute("SELECT COUNT(*) FROM unit WHERE id = ?", (id_unit,))
unit_check_exist = cursor.fetchone()[0]
if not unit_check_exist:
raise ValueError(f'Указанного id единицы измерения не существует!')
cursor.execute('''
INSERT INTO terminal_classifier (terminal_classifier_name, terminal_classifier_short_name, id_parent, id_unit)
VALUES (?, ?, ?, ?)
''', (terminal_classifier_name, terminal_classifier_short_name, id_parent, id_unit))
conn.commit()
print('Категория успешно добавлена.')
except Exception as _ex:
print(f'Error {_ex} - ошибка при добавлении категории.')
def add_subcategory(terminal_classifier_name, subterminal_classifier_name, subterminal_classifier_short_name, id_unit=None):
try:
if is_category_exists(terminal_classifier_name):
# Получаем Id категории
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_parent_to_set = cursor.fetchone()[0]
add_category(subterminal_classifier_name, subterminal_classifier_short_name, id_parent_to_set, id_unit)
conn.commit()
print("Подкатегория успешно добавлена.")
else:
print("Указанная категория/подкатегория не существует.")
except Exception as _ex:
print(f"Произошла ошибка при добавлении подкатегории: {_ex}")
def edit_category(id, terminal_classifier_name_new, terminal_classifier_short_name_new, id_unit=None):
try:
cursor.execute('SELECT COUNT(*) FROM terminal_classifier WHERE id = ?', (id,))
if cursor.fetchone()[0] == 0:
raise ValueError(f"Запись с id={id} не найдена в таблице terminal_classifier.")
if id_unit is not None:
cursor.execute('SELECT COUNT(*) FROM unit WHERE id = ?', (id_unit,))
if cursor.fetchone()[0] == 0:
raise ValueError(f"Запись с id_unit={id_unit} не найдена в таблице unit.")
cursor.execute('SELECT COUNT(*) FROM terminal_classifier WHERE terminal_classifier_name = ? AND id != ?', (terminal_classifier_name_new, id))
if cursor.fetchone()[0] > 0:
raise ValueError(f"Новое полное имя '{terminal_classifier_name_new}' уже занято.")
cursor.execute('SELECT COUNT(*) FROM terminal_classifier WHERE terminal_classifier_short_name = ? AND id != ?', (terminal_classifier_short_name_new, id))
if cursor.fetchone()[0] > 0:
raise ValueError(f"Новое короткое имя '{terminal_classifier_short_name_new}' уже занято.")
cursor.execute('''
UPDATE terminal_classifier
SET terminal_classifier_name = ?,
terminal_classifier_short_name = ?,
id_unit = ?
WHERE id = ?
''', (terminal_classifier_name_new, terminal_classifier_short_name_new, id_unit, id))
# Подтверждаем изменения
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при изменении категории: {_ex}")
def add_product(product_name, terminal_classifier_name, quantity, price, unit_value ):
try:
if is_category_exists(terminal_classifier_name):
# Получаем id подкатегории по ее названию
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
category_id = cursor.fetchone()[0]
# Добавляем новое изделие в таблицу Изделие
cursor.execute("INSERT INTO product (id_category, product_name, quantity, price, unit_value) VALUES (?, ?, ?, ?, ?)",
(category_id, product_name, quantity, price, unit_value))
conn.commit()
print("Изделие успешно добавлено.")
else:
print("Указанная подкатегория не существует.")
except Exception as _ex:
print(f"Произошла ошибка при добавлении изделия: {_ex}")
def get_all_categories():
try:
cursor.execute("SELECT * FROM terminal_classifier")
categories_names = cursor.fetchall()
return categories_names
except Exception as _ex:
print(f"Произошла ошибка при получении категорий: {_ex}")
return None
def get_all_products():
try:
cursor.execute("SELECT * FROM product")
products_names = cursor.fetchall()
return products_names
except Exception as _ex:
print(f"Произошла ошибка при получении товаров: {_ex}")
return None
def product_update_price(product_name, new_price):
try:
if is_product_exist(product_name):
cursor.execute("UPDATE product SET price = ? WHERE product_name = ?", (new_price, product_name))
conn.commit()
print('Цена изделия успешно обновлена.')
else:
print('Указанное изделие не существует.')
except Exception as _ex:
print(f"Произошла ошибка при обновлении цены изделия: {_ex}")
def product_update_quantity(product_name, new_quantity):
try:
if is_product_exist(product_name):
cursor.execute("UPDATE product SET quantity = ? WHERE product_name = ?", (new_quantity, product_name))
conn.commit()
print('Количество изделия успешно обновлено.')
else:
print('Указанное изделие не существует.')
except Exception as _ex:
print(f"Произошла ошибка при обновлении цены изделия: {_ex}")
def change_product_category(product_name, new_category):
try:
if is_category_exists(new_category):
# Получаем идентификатор новой категории
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (new_category,))
new_category_id = cursor.fetchone()[0]
# Обновляем категорию у изделия
cursor.execute("UPDATE product SET id_category = ? WHERE product_name = ?", (new_category_id, product_name))
conn.commit()
print('Категория изделия успешно изменена.')
else:
print('Указанная новая подкатегория не существует.')
except Exception as _ex:
print(f"Произошла ошибка при изменении подкатегории изделия: {_ex}")
def change_product_unit_value(product_name, unit_value):
try:
if is_product_exist(product_name):
cursor.execute("UPDATE product SET unit_value = ? WHERE product_name = ?", (unit_value, product_name))
conn.commit()
print('Значение единицы измерения изделия успешно изменено.')
else:
print('Указанное изделие не существует.')
except Exception as _ex:
print(f"Произошла ошибка при изменении значения единицы измерения изделия: {_ex}")
def delete_product_unit_value(product_name):
try:
if is_product_exist(product_name):
# cursor.execute("SELECT id_unit FROM product WHERE product_name = ?", (product_name,))
# delete_unit_id = cursor.fetchone()[0]
cursor.execute("UPDATE product SET unit_value = ? WHERE product_name = ?", (None, product_name))
conn.commit()
print('Значение единицы измерения изделия успешно удалено.')
else:
print('Указанное изделие не существует.')
except Exception as _ex:
print(f"Произошла ошибка при удалении значения единицы измерения изделия: {_ex}")
def is_enum_exist(terminal_classifier_name):
try:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
check_if_exist = cursor.fetchone()
return check_if_exist
except Exception as _ex:
print(f"Произошла ошибка при проверке перечисления на существование: {_ex}")
def is_enum_pos_exist(enum_name):
try:
cursor.execute("SELECT id FROM enum WHERE enum_name = ?", (enum_name,))
check_if_exist = cursor.fetchone()
if check_if_exist:
return True
else:
return False
except Exception as _ex:
print(f"Произошла ошибка при проверке перечисления на существование: {_ex}")
def add_enum_pos(enum_id, enum_name, enum_short_name, enum_description=None, real_value=None, int_value=None, str_value=None, priority=None):
try:
if is_enum_pos_exist(enum_name) and (not (enum_name == 'значение параметра' and enum_short_name == 'знчн прмтр')):
print("Указанное перечисление уже существует.")
return
# Get next priority if not provided
if priority is None:
cursor.execute("SELECT COALESCE(MAX(priority), 0) + 1 FROM enum", ())
priority = cursor.fetchone()[0]
# UPDATE via id
cursor.execute("INSERT INTO enum (enum_id, enum_name, enum_short_name, enum_description, real_value, int_value, str_value, priority) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
(enum_id, enum_name, enum_short_name, enum_description, real_value, int_value, str_value, priority))
conn.commit()
print('Перечисление успешно добавлено.')
except Exception as _ex:
print(f"Произошла ошибка при добавлении перечисления: {_ex}")
def delete_enum_classification(terminal_classifier_name):
try:
if is_enum_exist(terminal_classifier_name):
# Получаем идентификатор удаляемого класса перечислений
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
delete_id = cursor.fetchone()[0]
# Перемещаем все классы перечисления удаляемого класса перечисления в класс-перечисление "неопределенные"
cursor.execute("UPDATE terminal_classifier SET id_parent = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'неопределенные') WHERE id_parent = ?", (delete_id,))
# Перемещаем все перечисления удаляемой категории в категорию "неопределенные"
cursor.execute("UPDATE enum SET enum_id = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'неопределенные') WHERE enum_id = ?", (delete_id,))
# Удаляем класс-перечисление
cursor.execute("DELETE FROM terminal_classifier WHERE id = ?", (delete_id,))
conn.commit()
print('Класс перечисления успешно удален.')
else:
print('Указанный класс перечисления не существует.')
except Exception as _ex:
print(f"Произошла ошибка при удалении класса перечисления: {_ex}")
def delete_enum_pos(enum_name):
try:
# Удаление перечисления
cursor.execute("DELETE FROM enum WHERE enum_name = ?", (enum_name,))
rows_deleted = cursor.rowcount
if rows_deleted > 0:
print('Перечисление успешно удалено.')
else:
print('Перечисление с указанным названием не найдено.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при удалении перечисления: {_ex}")
def change_enum_pos(id, new_enum_name, new_enum_short_name, new_enum_description=None, new_real_value=None, new_int_value=None, new_str_value=None):
try:
cursor.execute("SELECT enum_name FROM enum WHERE id = ?", (id,))
old_name_to_check = cursor.fetchone()[0]
if is_enum_pos_exist(old_name_to_check):
cursor.execute("UPDATE enum SET enum_name = ?, enum_short_name = ?, enum_description = ?, real_value = ?, int_value = ?, str_value = ? WHERE id = ?",
(new_enum_name, new_enum_short_name, new_enum_description, new_real_value, new_int_value, new_str_value, id))
conn.commit()
print('Перечисление изменено.')
else:
print('Указаное перечисление не найдено.')
return
except Exception as _ex:
print(f"Произошла ошибка при изменении перечисления: {_ex}")
def edit_enum_pos_priority(enum_pos_id, new_priority):
try:
# Получаем enum_id для указанного enum_pos_id
cursor.execute("SELECT enum_id FROM enum WHERE id = ?", (enum_pos_id,))
result = cursor.fetchone()
if result is None:
print('Указанное enum_pos_id не найдено.')
return None
enum_id = result[0]
# Проверяем, существует ли уже запись с таким priority для данного enum_id
cursor.execute("""
SELECT count(*)
FROM enum
WHERE priority = ?
AND enum_id = ?
""", (new_priority, enum_id))
count = cursor.fetchone()[0]
if count == 0:
# Обновляем priority
cursor.execute("""
UPDATE enum
SET priority = ?
WHERE id = ?
""", (new_priority, enum_pos_id))
else:
# Смещаем приоритеты и обновляем нужную запись
cursor.execute("""
UPDATE enum
SET priority = priority + 1
WHERE priority >= ?
AND enum_id = ?
""", (new_priority, enum_id))
cursor.execute("""
UPDATE enum
SET priority = ?
WHERE id = ?
""", (new_priority, enum_pos_id))
conn.commit()
print("Приоритет перечисления изменен")
return new_priority
except Exception as _ex:
print(f"Произошла ошибка при изменении приоритета перечисления: {_ex}")
def find_enums(enum_class_id):
try:
cursor.execute("""
SELECT ep.id, ep.enum_name, ep.enum_short_name, ep.enum_id, ep.priority, ep.real_value, ep.int_value, ep.str_value
FROM enum ep
WHERE ep.enum_id = ?
ORDER BY ep.priority ASC
""", (enum_class_id,))
results = cursor.fetchall()
for row in results:
print(row)
return results
except Exception as _ex:
print(f"Произошла ошибка при получении списка перечислений заданного класса: {_ex}")
def add_enum_in_classifier(terminal_classifier_name, terminal_classifier_short_name, enum_parent_name, id_unit=None):
try:
if (is_category_exists(terminal_classifier_name)):
raise ValueError(f'перечисление с именем \"{terminal_classifier_name}\" уже существует в таблице {TERMINAL_CLASSIFIER_TABLE}')
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (enum_parent_name,))
id_parent_check = cursor.fetchone()
if id_parent_check is not None:
id_parent = id_parent_check[0]
else:
id_parent = None
if id_unit:
cursor.execute("SELECT COUNT(*) FROM unit WHERE id = ?", (id_unit,))
count = cursor.fetchone()[0]
if (not count):
print(f'Произошла ошибка при добавлении записи в enum_classifier! Указанного id_unit не существует.')
cursor.execute('''
INSERT INTO terminal_classifier (terminal_classifier_name, terminal_classifier_short_name, id_parent, id_unit)
VALUES (?, ?, ?, ?)
''', (terminal_classifier_name, terminal_classifier_short_name, id_parent, id_unit))
conn.commit()
print('Класс перечисления успешно добавлен в основную базу.')
except Exception as _ex:
print(f'Error {_ex} - ошибка при добавлении enum_in_classifier.')
def change_enum_priority(enum_name, priority):
try:
if (priority >= 0):
cursor.execute("UPDATE enum SET priority = ? WHERE enum_name = ?", (priority, enum_name))
conn.commit()
else:
print('Приоритет должен быть неотрицательным целым числом.')
return
except Exception as _ex:
print(f'Error {_ex} - ошибка при изменении приоритета конкретного перечисления.')
def check_cyclic_dependency_terminal_classifier(new_parent_terminal_classifier_id, product_name_in_func):
try:
def fetch_parent_terminal_classifier(id):
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE id = ?", (id,))
return cursor.fetchone()[0]
current_id = new_parent_terminal_classifier_id
while current_id is not None:
if current_id == product_name_in_func:
return True
current_id = fetch_parent_terminal_classifier(current_id)
return False
except Exception as _ex:
print(f'Error {_ex} - ошибка при проверке классов на цикл.')
def change_parent_of_terminal_classifier(terminal_classifier_name, new_parent_terminal_classifier=None):
try:
print(f'введенные категории - для {terminal_classifier_name} назначить родителем {new_parent_terminal_classifier}')
if (is_enum_exist(terminal_classifier_name)):
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_enum = cursor.fetchone()[0]
if (new_parent_terminal_classifier is not None):
if (is_enum_exist(new_parent_terminal_classifier)):
if (terminal_classifier_name == new_parent_terminal_classifier):
print('Нельзя назначить классу самого себя в родители.')
return 0
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (new_parent_terminal_classifier,))
id_new_parent_terminal_classifier = cursor.fetchone()[0]
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_parent_class_of_class = cursor.fetchone()[0]
# Check for cyclic dependency using the recursive function
if check_cyclic_dependency_terminal_classifier(id_new_parent_terminal_classifier, id_enum):
if (id_parent_class_of_class):
# if parent class has had their own parent then would set it
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_new_parent_terminal_classifier, id_enum))
conn.commit()
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_parent_class_of_class, id_new_parent_terminal_classifier ))
conn.commit()
print('Родитель у подкласса был успешно изменен.')
return 1
else:
# if not then class becomes root
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE terminal_classifier_name = ?", (None, new_parent_terminal_classifier))
conn.commit()
print(f'Подкласс c terminal_classifier_name - {new_parent_terminal_classifier} стала родительской.')
return 1
# Update the parent class
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_new_parent_terminal_classifier, id_enum ))
conn.commit()
return 1
else:
print('Новая родительский класс не существует.')
return 0
else:
# code for new_parent_class=None
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (None, id_enum))
conn.commit()
print('Класс стал корневым / одним из корневых')
return 1
else:
print('Указанного класса не существует.')
return 0
except Exception as _ex:
conn.rollback()
print(f"Ошибка в изменении родителя класса (terminal_classifier): {_ex}")
def delete_product(product_name):
try:
# Удаление изделия
cursor.execute("DELETE FROM product WHERE product_name = ?", (product_name,))
rows_deleted = cursor.rowcount
if rows_deleted > 0:
print('Изделие успешно удалено.')
else:
print('Изделие с указанным названием не найдено.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при удалении изделия: {_ex}")
def delete_product_by_id(prod_id):
try:
# Удаление изделия
cursor.execute("DELETE FROM product WHERE id = ?", (prod_id,))
rows_deleted = cursor.rowcount
if rows_deleted > 0:
print('Изделие успешно удалено.')
else:
print('Изделие с указанным id не найдено.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при удалении изделия: {_ex}")
def delete_category(terminal_classifier_name):
try:
if is_category_exists(terminal_classifier_name):
# Получаем идентификатор удаляемой категории
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?;", (terminal_classifier_name,))
delete_id = cursor.fetchone()[0]
# Перемещаем все подкатегории удаляемой категории в категорию "неопределенные"
cursor.execute("UPDATE terminal_classifier SET id_parent = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'неопределенные') WHERE id_parent = ?", (delete_id,))
# Перемещаем все изделия удаляемой категории в категорию "неопределенные"
cursor.execute("UPDATE product SET id_category = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'неопределенные') WHERE id_category = ?", (delete_id,))
# Удаляем категорию
cursor.execute("DELETE FROM terminal_classifier WHERE id = ?", (delete_id,))
conn.commit()
print('Категория успешно удалена.')
else:
print('Указанная категория не существует.')
except Exception as _ex:
print(f"Произошла ошибка при удалении категории: {_ex}")
# вроде воркает с подтягиванием к 1 ноде 3ей ноды, при удалении 2
def delete_subcategory(subterminal_classifier_name):
try:
if is_category_exists(subterminal_classifier_name):
# Получаем идентификатор и родительский идентификатор удаляемой подкатегории
cursor.execute("SELECT id, id_parent FROM terminal_classifier WHERE terminal_classifier_name = ?", (subterminal_classifier_name,))
result = cursor.fetchone()
if not result:
print('Указанная подкатегория не существует.')
return
subcategory_id, parent_id = result
# Если есть родительская категория
if parent_id:
# Обновляем родителя потомков удаляемой подкатегории на родителя удаляемой подкатегории
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id_parent = ?", (parent_id, subcategory_id))
else:
# Если родителя нет, перемещаем детей в "категория неопределенное"
cursor.execute("UPDATE terminal_classifier SET id_parent = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'категория неопределенное') WHERE id_parent = ?", (subcategory_id,))
# Перемещаем связанные изделия в категорию "неопределенные"
cursor.execute("UPDATE product SET id_category = (SELECT id FROM terminal_classifier WHERE terminal_classifier_name = 'категория неопределенное') WHERE id_category = ?", (subcategory_id,))
# Удаляем подкатегорию
cursor.execute("DELETE FROM terminal_classifier WHERE id = ?", (subcategory_id,))
conn.commit()
print('Подкатегория успешно удалена.')
else:
print('Указанная подкатегория не существует.')
except Exception as _ex:
print(f"Произошла ошибка при удалении подкатегории: {_ex}")
def get_subcategory_parent(subterminal_classifier_name):
try:
if is_category_exists(subterminal_classifier_name):
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE terminal_classifier_name = ?", (subterminal_classifier_name,))
id_parent_category_of_subcategory = cursor.fetchone()[0]
cursor.execute("SELECT terminal_classifier_name FROM terminal_classifier WHERE id = ?", (id_parent_category_of_subcategory,))
parent_terminal_classifier_name = cursor.fetchone()[0]
return parent_terminal_classifier_name
else:
print('Указанной подкатегории не существует!')
except Exception as _ex:
print(f"Произошла ошибка при получении родительской категории подкатегории: {_ex}")
# cycle checking
def check_cyclic_dependency(new_parent_id, category_id):
def fetch_parent_category(cat_id):
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE id = ?", (cat_id,))
return cursor.fetchone()[0]
current_id = new_parent_id
while current_id is not None:
if current_id == category_id:
return True
current_id = fetch_parent_category(current_id)
return False
def change_parent_of_category(terminal_classifier_name, new_parent_category=None):
try:
print(f'введенные категории - для {terminal_classifier_name} назначить родителем {new_parent_category}')
if (is_category_exists(terminal_classifier_name)):
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_category = cursor.fetchone()[0]
if (new_parent_category is not None):
if (is_category_exists(new_parent_category)):
if (terminal_classifier_name == new_parent_category):
print('Нельзя назначить категории саму себя в родители.')
return
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (new_parent_category,))
id_new_parent_category = cursor.fetchone()[0]
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_parent_category_of_category = cursor.fetchone()[0]
# Check for cyclic dependency using the recursive function
if check_cyclic_dependency(id_new_parent_category, id_category):
if (id_parent_category_of_category):
# if parent category has had their own parent then would set it
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_new_parent_category, id_category))
conn.commit()
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_parent_category_of_category, id_new_parent_category ))
conn.commit()
print('Родитель у подкатегории был успешно изменен.')
else:
# if not then category becomes root
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE terminal_classifier_name = ?", (None, new_parent_category))
conn.commit()
print(f'Подкатегория c terminal_classifier_name {new_parent_category} стала родительской.')
# Update the parent category
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (id_new_parent_category, id_category ))
conn.commit()
else:
print('Новая родительская категория не существует.')
else:
# code for new_parent_category=None
cursor.execute("UPDATE terminal_classifier SET id_parent = ? WHERE id = ?", (None, id_category))
conn.commit()
print('Категория стала корневой / одной из корневых')
else:
print('Указанной категории не существует.')
except Exception as _ex:
conn.rollback()
print(f"Ошибка в изменении родителя категории: {_ex}")
def change_terminal_classifier_name(old_name, new_name):
try:
if is_category_exists(old_name):
if not is_category_exists(new_name):
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (old_name,))
terminal_classifier_name_id = cursor.fetchone()[0]
cursor.execute("UPDATE category SET terminal_classifier_name = ? WHERE id = ?", (new_name, terminal_classifier_name_id))
print('Имя категории успешно изменено.')
else:
print('Указанное новое имя категории уже существует!')
else:
print('Указанная категория не существует.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при изменении имени категории: {_ex}")
def change_product_name(old_name, new_name):
try:
if is_product_exist(old_name):
if not is_product_exist(new_name):
cursor.execute("SELECT id FROM product WHERE product_name = ?", (old_name,))
product_name_id = cursor.fetchone()[0]
cursor.execute("UPDATE product SET product_name = ? WHERE id = ?", (new_name, product_name_id))
print('Имя изделия успешно изменено.')
else:
print('Указанное новое имя изделия уже существует!')
else:
print('Указанное изделие не существует.')
conn.commit()
except Exception as _ex:
print(f"Произошла ошибка при изменении имени изделия: {_ex}")
def get_category_parents(terminal_classifier_name):
if is_category_exists(terminal_classifier_name):
terminal_classifier_name_copy = terminal_classifier_name
try:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
category_id = cursor.fetchone()[0]
# function for recursive search parents
def find_parents(category_id, parents_list):
id_parent = 0
cursor.execute("SELECT EXISTS(SELECT 1 FROM terminal_classifier WHERE id = ?)", (category_id,))
record_exists = cursor.fetchone()[0]
if record_exists:
cursor.execute("SELECT id_parent FROM terminal_classifier WHERE id = ?", (category_id,))
id_parent = cursor.fetchone()[0]
if id_parent == 0:
return
if category_id != 0 and id_parent != 0:
if id_parent != 0:
cursor.execute("SELECT terminal_classifier_name FROM terminal_classifier WHERE id = ?", (id_parent,))
parent_name = cursor.fetchone()
parents_list.append(parent_name)
find_parents(id_parent, parents_list)
parents_list = []
parents_list_res = []
# begin recursive search for parents
find_parents(category_id, parents_list)
for elem in parents_list:
if elem:
parents_list_res.append(elem[0])
if parents_list_res:
print(f'родительские элементы для категории "{terminal_classifier_name_copy}": \n {parents_list_res}')
else:
print(f'У категории "{terminal_classifier_name_copy}" нет родительских элементов')
except Exception as _ex:
print(f"Произошла ошибка при получении списка родителей категории: {_ex}")
else:
print('Категории не существует.')
def print_category_children(terminal_classifier_name, order):
if not is_category_exists(terminal_classifier_name):
print("Такой категории нет.")
return
children_list_res = get_category_children(terminal_classifier_name)
if children_list_res:
if order == 'прямой':
print(f'дочерние элементы для категории "{terminal_classifier_name}": \n {children_list_res}')
elif order == 'обратный':
print(f'дочерние элементы для категории "{terminal_classifier_name}": \n {children_list_res[::-1]}')
else:
print('Такого порядка вывода нет!')
else:
print(f'У категории "{terminal_classifier_name}" нет дочерних элементов')
def get_category_children(terminal_classifier_name):
if is_category_exists(terminal_classifier_name):
try:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
category_id = cursor.fetchone()[0]
# function for recursive search subcategories
def find_children(category_id, children_list):
childrens_id = 0
childrens_id = []
cursor.execute("SELECT COUNT(*) FROM terminal_classifier WHERE id_parent = ?", (category_id,))
record_exists = cursor.fetchall()
if record_exists:
cursor.execute("SELECT id FROM terminal_classifier WHERE id_parent = ?", (category_id,))
childrens_id = cursor.fetchall()
if childrens_id == 0:
return
if category_id != 0 and childrens_id != 0:
for elem in childrens_id:
elem_id = elem[0]
cursor.execute("SELECT terminal_classifier_name FROM terminal_classifier WHERE id = ?", (elem_id,))
child_name = cursor.fetchone()
children_list.append(child_name)
find_children(elem_id, children_list)
children_list = []
children_list_res = []
# begin search subcategories
find_children(category_id, children_list)
for elem in children_list:
if elem:
children_list_res.append(elem[0])
return children_list_res
except Exception as _ex:
print(f"Произошла ошибка при получении списка дочерних категорий: {_ex}")
else:
print('Категории не существует.')
############### added after first review ###############
def print_products_of_category(terminal_classifier_name, order):
products = get_products_of_category(terminal_classifier_name)
if products:
print(f'Изделия для категории "{terminal_classifier_name}":')
print_str = ''
if order == 'прямой':
for prod in products:
print_str += '"' + prod + '"' + ' '
print(print_str)
elif order == 'обратный':
products = products[::-1]
for prod in products:
print_str += '"' + prod + '"' + ' '
print(print_str)
else:
print('Такого порядка вывода нет!')
else:
print(f'У категории "{terminal_classifier_name}" нет изделий')
def get_products_of_category(terminal_classifier_name):
if is_category_exists(terminal_classifier_name):
try:
categories_to_check = get_category_children(terminal_classifier_name)
products = []
if categories_to_check:
for category in categories_to_check:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (category,))
id_of_searched_category = cursor.fetchone()[0]
cursor.execute("SELECT id FROM product WHERE id_category = ?", (id_of_searched_category,))
products_id = cursor.fetchall()
for id in products_id:
cursor.execute("SELECT product_name FROM product WHERE id = ?", (id[0],))
product_to_add = cursor.fetchone()[0]
products.append(product_to_add)
else:
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (terminal_classifier_name,))
id_of_searched_category = cursor.fetchone()[0]
cursor.execute("SELECT id FROM product WHERE id_category = ?", (id_of_searched_category,))
products_id = cursor.fetchall()
for id in products_id:
cursor.execute("SELECT product_name FROM product WHERE id = ?", (id[0],))
product_to_add = cursor.fetchone()[0]
products.append(product_to_add)
return products
except Exception as _ex:
print(f"Произошла ошибка при поиске изделия заданной категории: {_ex}")
else:
print('Категории не существует.')
##################################### third lab #####################################
def create_param(new_name, new_short_name, new_unit_id, new_min_val, new_max_val):
try:
cursor.execute('''SELECT unit_name FROM unit WHERE id = ?''', (new_unit_id,))
is_unit_exist = cursor.fetchone()
if not is_unit_exist:
print(f'Ошибка в create_param: Единицы измерения не сушествует.')
cursor.execute('''
INSERT INTO param(param_name, param_short_name, unit_id, min_val, max_val)
VALUES (?, ?, ?, ?, ?)
''', (new_name, new_short_name, new_unit_id, new_min_val, new_max_val))
# Проверка количества вставленных строк
if cursor.rowcount == 1:
conn.commit()
print(f'параметр с именем {new_name} успешно добавлен.')
return 1
else:
conn.rollback()
return 0
except sqlite3.Error as e:
# В случае ошибки откатываем транзакцию
print(f"An error occurred in create_param: {e}")
conn.rollback()
return 0
def edit_param(param_id, new_name, new_short_name, new_unit_id, new_min_val, new_max_val):
try:
# Начало транзакции
conn.execute('BEGIN TRANSACTION')
cursor.execute('''SELECT param_name FROM param WHERE id = ? ''', (param_id,))
is_param_exist = cursor.fetchone()
if not is_param_exist:
print(f'Ошибка в edit_param: Параметра с id = {param_id} не существует.')
return 0
cursor.execute('''SELECT unit_name FROM unit WHERE id = ? ''', (new_unit_id,))
is_unit_exist = cursor.fetchone()
if not is_unit_exist:
print(f'Ошибка в edit_param: Единицы измерения с id = {new_unit_id} не существует.')
return 0
# Выполнение запроса на обновление
cursor.execute('''
UPDATE param
SET param_name = ?, param_short_name = ?, unit_id = ?, min_val = ?, max_val = ?
WHERE id = ?
''', (new_name, new_short_name, new_unit_id, new_min_val, new_max_val, param_id))
conn.commit()
# Получение количества обновленных строк
res = cursor.rowcount
# Фиксация изменений
conn.commit()
# Возвращение результата
if res == 1:
print(f'Параметр с id = {param_id} успешно обновлен.')
return 1
else:
return 0
except sqlite3.Error as e:
print(f"Ошибка в edit_param: {e}")
conn.rollback()
return 0
def delete_param(param_to_delete):
cursor.execute('''SELECT id FROM param WHERE param_name = ? ''', (param_to_delete,))
param_id = cursor.fetchone()
if not param_id:
print(f'Ошибка. Параметра с таким названием не существует')
return 0
else:
param_id = param_id[0]
print(f'param_id - {param_id}')
def del_param_from__class_param():
cursor.execute('''SELECT id FROM class_param WHERE param_id = ? ''', (param_id,))
classes_id_to_del = cursor.fetchall()
print(f'classes_id_to_del - {classes_id_to_del}')
for elem_id in classes_id_to_del:
print(f'elem_id - {elem_id[0]}')
cursor.execute("DELETE FROM class_param WHERE id = ?", (elem_id[0],))
conn.commit()
print(f'Классы параметров (если были) удаляемого параметра были обновлены')
del_param_from__class_param()
cursor.execute("DELETE FROM param WHERE param_name = ?", (param_to_delete,))
res = cursor.rowcount
conn.commit()
# Возвращение результата в зависимости от количества удаленных строк
if res == 1:
print(f'Параметр успешно удален.')
return 1
else:
print(f'При удалении параметра что-то пошло не так.')
return 0
def create_class_param(terminal_classifier_name_class, terminal_classifier_name_short_class, param_name, parent_class_param_name=None):
try:
cursor.execute("SELECT id FROM param WHERE param_name = ?", (param_name,))
param_id = cursor.fetchone()
if not param_id:
print(f'Ошибка в create_class_param: параметра с именем {param_name} не существует в таблице param')
return 0
else:
param_id = param_id[0]
cursor.execute("SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ?", (parent_class_param_name,))
parent_class_id = cursor.fetchone()
if not parent_class_id:
print(f'В create_class_param: для параметра \"{terminal_classifier_name_class}\" класса параметра (родителя) с именем \"{parent_class_param_name}\" не существует в таблице \"terminal_classifier\", будет вставлено значение \"None\"')
parent_class_id = None
else:
parent_class_id = parent_class_id[0]
# Получаем максимальное значение priority для данного class_id
cursor.execute(''' SELECT COUNT(*) FROM class_param WHERE param_class_name = ? ''', (terminal_classifier_name_class,))
res = cursor.fetchone()[0]
if res is None:
res = 0
else:
cursor.execute(''' SELECT MAX(priority) + 1 FROM class_param WHERE param_class_name = ? ''', (terminal_classifier_name_class,))
res = cursor.fetchone()[0]
if res is None:
res = 0
cursor.execute('''SELECT unit_id FROM param WHERE param_name = ? ''', (param_name,))
unit_id = cursor.fetchone()
if not unit_id:
print(f'Единицы измерения с заданным {unit_id} не найдено. Будет вставлено NULL')
else:
unit_id = unit_id[0]
cursor.execute('''
INSERT INTO terminal_classifier(id_parent, terminal_classifier_name, terminal_classifier_short_name, id_unit, priority)
VALUES (?, ?, ?, ?, ?)
''', (parent_class_id, terminal_classifier_name_class, terminal_classifier_name_short_class, unit_id, res))
cursor.execute('''
INSERT INTO class_param(param_class_name, param_class_short_name, class_param_id, param_id, priority)
VALUES (?, ?, ?, ?, ?)
''', (terminal_classifier_name_class, terminal_classifier_name_short_class, parent_class_id, param_id, res))
conn.commit()
except sqlite3.Error as e:
# В случае ошибки откатываем транзакцию
print(f"An error occurred: {e}")
conn.rollback()
return 0
def edit_class_param(id, new_param_class_name, new_param_class_short_name, new_param_id=None, class_param_id=None):
try:
# Начало транзакции
conn.execute('BEGIN TRANSACTION')
cursor.execute('''SELECT param_class_name FROM class_param WHERE id = ? ''', (id,))
is_class_param_exist = cursor.fetchone()
if not is_class_param_exist:
print(f'Ошибка в edit_class_param: Параметра класса с id = {id} не существует.')
return 0
else:
param_class_name_old = is_class_param_exist[0]
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', (param_class_name_old,))
id_class_param_in_tc = cursor.fetchone()[0]
if new_param_id:
cursor.execute('''SELECT param_name FROM param WHERE id = ? ''', (new_param_id,))
is_param_exist = cursor.fetchone()
if not is_param_exist:
print(f'Ошибка в edit_class_param: Параметра с id = {new_param_id} не существует.')
return 0
else:
cursor.execute('''SELECT id FROM param WHERE param_name = ? ''', ('неопределенный параметр',))
new_param_id = cursor.fetchone()[0]
if class_param_id:
cursor.execute('''SELECT terminal_classifier_name FROM terminal_classifier WHERE id = ? ''', (class_param_id,))
is_terminal_class_name_exist = cursor.fetchone()
if check_cyclic_dependency_terminal_classifier(class_param_id, param_class_name_old):
print("Ошибка в edit_class_param: родитель и потомок образуют цикл. ")
return 0
if (is_terminal_class_name_exist[0] == param_class_name_old):
print(f'_terminal_class_name_ = {is_terminal_class_name_exist[0]}, param_class_name_old = {param_class_name_old} =>', sep='')
print(f'Нельзя назначить классу в родителя самого себя')
return 0
if not is_terminal_class_name_exist:
print(f'Ошибка в edit_class_param: Параметра класса с id = {id} не существует.')
return 0
if change_parent_of_category(param_class_name_old, is_terminal_class_name_exist[0]):
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', ('неопределенный параметр класса',))
class_param_id = cursor.fetchone()[0]
cursor.execute("UPDATE class_param SET param_class_name = ?, param_class_short_name = ?, param_id = ?, class_param_id = ? WHERE id = ?", (new_param_class_name, new_param_class_short_name, new_param_id, class_param_id, id))
cursor.execute("UPDATE terminal_classifier SET terminal_classifier_name = ?, terminal_classifier_short_name = ?, id_parent = ? WHERE id = ?", (new_param_class_name, new_param_class_short_name, class_param_id, id_class_param_in_tc))
res = cursor.rowcount
# Фиксация изменений
conn.commit()
# Возвращение результата
if res == 1:
print(f'Параметр с id = {id} успешно обновлен.')
return 1
else:
return 0
else:
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', ('неопределенный параметр класса',))
class_param_id = cursor.fetchone()[0]
cursor.execute("UPDATE class_param SET param_class_name = ?, param_class_short_name = ?, param_id = ?, class_param_id = ? WHERE id = ?", (new_param_class_name, new_param_class_short_name, new_param_id, class_param_id, id))
cursor.execute("UPDATE terminal_classifier SET terminal_classifier_name = ?, terminal_classifier_short_name = ?, id_parent = ? WHERE id = ?", (new_param_class_name, new_param_class_short_name, class_param_id, id_class_param_in_tc))
res = cursor.rowcount
# Фиксация изменений
conn.commit()
# Возвращение результата
if res == 1:
print(f'Параметр класса с id = {id} успешно обновлен.')
return 1
else:
return 0
except sqlite3.Error as e:
print(f"Ошибка в edit_class_param: {e}")
conn.rollback()
return 0
def delete_class_param(class_to_delete):
try:
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', (class_to_delete,))
exists = cursor.fetchone()
if not exists:
print(f'Ошибка в delete_class_param: Класса параметра с таким названием не существует')
return 0
if (class_to_delete == 'неопределенный параметр класса' or class_to_delete == 'параметр класса'):
print(f"Нельзя удалить параметр класса \'неопределенный параметр класса\' или \'параметр класса\'")
return 0
# Проверка на наличие дочерних элементов
is_children_exist = get_category_children(class_to_delete)
print(f'is_children_exist - {is_children_exist}')
if not is_children_exist:
cursor.execute("DELETE FROM class_param WHERE param_class_name = ?", (class_to_delete,))
conn.commit()
cursor.execute("DELETE FROM terminal_classifier WHERE terminal_classifier_name = ?", (class_to_delete,))
conn.commit()
else:
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', (class_to_delete,))
id_class_to_delete = cursor.fetchone()[0]
print(f'class_to_delete - {class_to_delete}')
print(f'id_class_to_delete - {id_class_to_delete}')
cursor.execute("SELECT id FROM class_param WHERE class_param_id = ? ", (id_class_to_delete,))
children = cursor.fetchall()
print(f'children (id) - {children}')
cursor.execute('''SELECT id FROM terminal_classifier WHERE terminal_classifier_name = ? ''', ('неопределенный параметр класса',))
undef_class_id = cursor.fetchone()[0]
children_info_rows = []
for child in children:
print(f'child - {child}')
cursor.execute('''SELECT param_class_name FROM class_param WHERE id = ? ''', (child[0],))
child_name = cursor.fetchone()[0]
print(f'child_name - {child_name}')
cursor.execute('''SELECT * FROM class_param WHERE id = ?''', (child[0],))
child_row = cursor.fetchone()[0]
children_info_rows.append(child_row)
cursor.execute("UPDATE class_param SET class_param_id = ? WHERE id = ?", (undef_class_id, child[0]))
change_parent_of_terminal_classifier(child_name, 'неопределенный параметр класса')
conn.commit()
cursor.execute("DELETE FROM class_param WHERE param_class_name = ?", (class_to_delete,))
conn.commit()
cursor.execute("DELETE FROM terminal_classifier WHERE terminal_classifier_name = ?", (class_to_delete,))
conn.commit()
print(f'children_info_rows - {children_info_rows}')
conn.commit()
print("Удаление завершено успешно")
return 1
except sqlite3.IntegrityError as e:
print(f"Ошибка в delete_class_param: {e}")
conn.rollback()
return 0
def inherit_class_parameters(new_class_to_inherit__name, new_class_to_inherit__short_name, parent_class__name):
try:
# Получаем parent_id
cursor.execute('''
SELECT id FROM class_param WHERE param_class_name = ?
''', (parent_class__name,))
parent_id_row = cursor.fetchone()
if parent_id_row is None:
print(f'Ошибка в inherit_class_parameters: класса параметра с именем для наследования не найдено')
return 0 # Если id родителя в таблице class_param не найдено
# Получаем параметры из CLASS_PARAM для parent_id
cursor.execute('''
SELECT class_param_id, param_id FROM class_param WHERE param_class_name = ? ORDER BY priority
''', (parent_class__name,))
param_rows = cursor.fetchall()
print(f'param_rows - {param_rows}')
for param_row in param_rows:
class_param_id, param_id = param_row
# Проверяем, существует ли уже параметр для данного cl_id
cursor.execute('''
SELECT 1 FROM class_param WHERE param_class_name = ? AND param_id = ?
''', (new_class_to_inherit__name, param_id))
exists = cursor.fetchone()
cursor.execute('''
SELECT param_name FROM param WHERE id = ?''', (param_id,))
param_name = cursor.fetchone()[0]
print(f'exists ? - {exists}')
if exists:
print(f'Класс параметра с именем {new_class_to_inherit__name} уже существует.')
if not exists:
create_class_param(new_class_to_inherit__name, new_class_to_inherit__short_name, param_name, parent_class__name)
conn.commit()
except sqlite3.Error as e:
print(f"An error occurred in inherit_class_parameters: {e}")
conn.rollback()
return 0
def edit_class_param_output_priority(class_id, id, priority):
try:
# Выполнение запроса для получения количества записей с указанным priority и id класса
cursor.execute("""
SELECT count(*)
FROM class_param
WHERE priority = ? AND class_param_id = ?
""", (priority, class_id))
# Получение результата запроса
cnt = cursor.fetchone()[0]
if cnt == 0:
# Если таких записей нет, обновляем priority для указанной записи
cursor.execute("""
UPDATE class_param
SET priority = ?
WHERE class_param_id = ? AND id = ?
""", (priority, class_id, id))
else:
# Если такие записи есть, увеличиваем output_priority для всех записей с priority >= переданного в функцию priority
cursor.execute("""
UPDATE class_param
SET priority = priority + 1
WHERE priority >= ? AND class_param_id = ?
""", (priority, class_id))
# Затем обновляем priority для указанной записи
cursor.execute("""
UPDATE class_param
SET priority = ?
WHERE class_param_id = ? AND id = ?
""", (priority, class_id, id))
conn.commit()
print(f'Приоритет изменен.')
return priority
except sqlite3.Error as e:
print(f"An error occurred in edit_class_param_output_priority: {e}")
conn.rollback()
return 0
def is_param_allowed_to_prod_category(param_id, prod_id):
try:
if not (is_exist_by_id_in_table(param_id, PARAM_TABLE)):
raise ValueError(f'параметра с id={param_id} не существует в таблице {PARAM_TABLE}')
if not (is_exist_by_id_in_table(prod_id, PRODUCT_TABLE)):
raise ValueError(f'продукции с id={prod_id} не существует в таблице {PRODUCT_TABLE}')
cursor.execute("SELECT id_category FROM product WHERE id = ?", (prod_id,))
product_id_category = cursor.fetchone()
if product_id_category:
product_id_category = product_id_category[0]
print(f'- - product_id_category - {product_id_category}')
cursor.execute("SELECT id FROM class_param WHERE param_id = ? AND class_param_id = ?", (param_id, product_id_category))
class_param_id_row = cursor.fetchone()
# print(f'- - class_param_id_row - {class_param_id_row}')
if class_param_id_row:
return True
else:
return False
except sqlite3.Error as e:
print(f"An error occurred in is_param_allowed_to_prod: {e}")
conn.rollback()
return 0
def create_prod_param(new_prod_id, new_param_id, is_configurable):
try:
cursor.execute("SELECT product_name FROM product WHERE id = ?", (new_prod_id,))
is_new_product_name_exist = cursor.fetchone()
if is_new_product_name_exist is None:
print(f'Ошибка в create_prod_param: изделия с id {new_prod_id} не найдено')
return 0
cursor.execute('''
SELECT param_name FROM param WHERE id = ?
''', (new_param_id,))
is_new_param_name_exist = cursor.fetchone()
if is_new_param_name_exist is None:
print(f'Ошибка в create_prod_param: параметра с id {new_param_id} не найдено')
return 0
# проверяем, является ли изделие вариантом исполнения
cursor.execute('''
SELECT configurable_type FROM product WHERE id = ?
''', (new_prod_id,))
configurable_type = cursor.fetchone()[0]
if configurable_type == 0:
raise ValueError(f'Вы пытаетесь задать значения параметров обычному изделию с типом 0, которое не может быть параметризовано. Вместо этого, сначала сделайте конфигурацию для этой продукции через функцию create_configuration_product_by_existing_prod_id')
# 2-3 lab check
if not (is_param_allowed_to_prod_category(new_param_id, new_prod_id)):
raise ValueError(f'ошибка! для продукции с id={new_prod_id} параметр с id={new_param_id} является недопустимым. \nЕсли параметр должен быть допустимым, добавьте запись в таблицу class_param с id параметра из таблицы param и class_param_id(id_category в таблице terminal_classifier) для продукции соотвествующей category')
# 2-3 lab check
if not (isinstance(is_configurable, bool)):
raise ValueError(f'значения переданного аргумента is_configurable={is_configurable} не является bool')
cursor.execute('''
INSERT INTO prod_param (prod_id, param_id, is_configurable)
VALUES (?, ?, ?)
''', (new_prod_id, new_param_id, is_configurable))
res = cursor.rowcount
conn.commit()
if res == 1:
print(f'\nДобавлена запись в таблицу prod_param\n')
return 1
else:
return 0
except sqlite3.Error as e:
print(f"Ошибка в create_prod_param: {e}")
conn.rollback()
return 0
def fill_prod_param(prod_id, param_id, new_int_val, new_real_val, new_str_val):
try:
# Validate product and parameter existence
if not is_exist_by_id_in_table(prod_id, PRODUCT_TABLE):
raise ValueError(f'нет продукта с таким prod_id={prod_id} в таблице product')
if not is_exist_by_id_in_table(param_id, PARAM_TABLE):
raise ValueError(f'нет параметра с таким param_id={param_id} в таблице param')
cursor.execute('''
SELECT configurable_type FROM product WHERE id = ?
''', (prod_id,))
configurable_type = cursor.fetchone()[0]
if configurable_type in [0, 1]:
variant = ''
if configurable_type == 0:
variant = 'продукция без конфигуратора'
if configurable_type == 1:
variant = 'продукция с конфигуратора'
raise ValueError(f'ошибка! заполнение параметров для продукции доступно только для варианта исполнения. тип введеного id продукции = {variant}')
# Validate new_int_val range
if new_int_val is not None:
cursor.execute('''SELECT min_val, max_val FROM param WHERE id = ?''', (param_id,))
min_val, max_val = cursor.fetchone()
if not (min_val <= new_int_val <= max_val):
raise ValueError(f'значение {new_int_val} не попадает в промежуток границ параметра [{min_val} ; {max_val}]')
# Validate new_real_val range
if new_real_val is not None:
cursor.execute('''SELECT min_val, max_val FROM param WHERE id = ?''', (param_id,))
min_val, max_val = cursor.fetchone()
if not (min_val <= new_real_val <= max_val):
raise ValueError(f'значение {new_real_val} не попадает в промежуток границ параметра [{min_val} ; {max_val}]')
# Проверка существования записи
cursor.execute('''
SELECT COUNT(*) FROM prod_param WHERE prod_id = ? AND param_id = ?
''', (prod_id, param_id))
exists = cursor.fetchone()[0]
if exists:
# Обновление существующей записи
cursor.execute('''
UPDATE prod_param
SET int_value = ?, str_value = ?, real_value = ?
WHERE prod_id = ? AND param_id = ?
''', (new_int_val, new_str_val, new_real_val, prod_id, param_id))
else:
# Добавление новой записи
cursor.execute('''
INSERT INTO prod_param (prod_id, param_id, int_value, str_value, real_value)
VALUES (?, ?, ?, ?, ?)
''', (prod_id, param_id, new_int_val, new_str_val, new_real_val))
# Проверка успешности операции
cursor.execute('''
SELECT int_value, str_value, real_value
FROM prod_param
WHERE prod_id = ? AND param_id = ?
''', (prod_id, param_id))
updated_row = cursor.fetchone()
if (updated_row == (new_int_val, new_str_val, new_real_val)):
print(f'для изделия с prod_id={prod_id} обновлены или добавлены параметры с param_id={param_id}')
conn.commit()
return 1
else:
raise ValueError(f'не получилось вставить или обновить значения параметра с param_id={param_id} для изделия с prod_id={prod_id}')
except sqlite3.Error as e:
print(f"Ошибка в fill_prod_param: {e}")
conn.rollback()
return 0
# вроде не очень
def edit_prod_param(id, new_int_val, new_str_val, new_real_val, new_enum_val):
try:
# Начало транзакции
conn.execute('BEGIN TRANSACTION')
new_enum_val
# проверка на существование new_enum_val
cursor.execute('''
SELECT id FROM enum WHERE enum_name = ?
''', (new_enum_val,))
is_enum_exist = cursor.fetchall()
print(f'is_enum_exist - {is_enum_exist}')
if is_enum_exist is None:
print(f'Ошибка в edit_prod_param: записи с new_enum_val {new_enum_val} в enum не найдено')
return 0
else:
new_enum_id = is_enum_exist[0]
# проверка на существование id
cursor.execute('''
SELECT prod_id, param_id FROM prod_param WHERE id = ?
''', (id,))
is_id_exist = cursor.fetchall()
print(f'is_id_exist - {is_id_exist}')
if is_id_exist is None:
print(f'Ошибка в edit_prod_param: записи с id {id} в prod_param не найдено')
return 0
print(f'enum_id - {new_enum_id[0]}')
# Выполнение запроса на обновление данных
cursor.execute('''
UPDATE prod_param
SET int_value = ?, str_value = ?, enum_id = ?, real_value = ?
WHERE id = ?
''', (new_int_val, new_str_val, new_enum_id[0], new_real_val, id))
# Получение количества обновленных строк
res = cursor.rowcount
# Фиксация изменений
conn.commit()
# Возвращение результата
if res == 1:
return 1
else:
return 0
except sqlite3.Error as e:
print(f"Ошибка в edit_prod_param: {e}")
conn.rollback()
return 0
def find_param_id_from_prod(prod_id):
try:
cursor.execute('SELECT product_name FROM product WHERE id = ?', (prod_id,))
product_name = cursor.fetchone()
if product_name:
product_name = product_name[0]
else:
print(f'изделия с id - {prod_id} не существует.')
return 0
# Начало транзакции
conn.execute('BEGIN TRANSACTION')
# Получение class_id из таблицы obj
cursor.execute('SELECT id_category FROM product WHERE id = ?', (prod_id,))
id_parent = cursor.fetchone()
print(f'id_parent = {id_parent}')
if id_parent is None:
print(f'Ошибка: объект с id {prod_id} не найден')
return []
id_parent = id_parent[0]
# Получение param_id из таблицы class_param, упорядоченных по output_priority
cursor.execute('''
SELECT param_id FROM class_param
WHERE class_param_id = ?
ORDER BY priority
''', (id_parent,))
param_ids = cursor.fetchall()
# Фиксация изменений
conn.commit()
# Возвращение результата в виде списка
return [row[0] for row in param_ids]
except sqlite3.Error as e:
print(f"Ошибка в find_param_id_from_prod: {e}")
conn.rollback()
return []
def find_products_of_class_param(id_of_class_param_el):
cursor.execute('SELECT param_class_name FROM class_param WHERE id = ?', (id_of_class_param_el,))
name_of_class_param_el = cursor.fetchone()
print(f'id_of_class_param_el - {name_of_class_param_el}')
if name_of_class_param_el:
name_of_class_param_el = name_of_class_param_el[0]
else:
print(f'класса параметра с названием - {name_of_class_param_el} не существует.')
return 0
cursor.execute('SELECT class_param_id FROM class_param WHERE id = ?', (id_of_class_param_el,))
class_param_id = cursor.fetchone()
print(f'name_of_class_param_el - {name_of_class_param_el}')
if class_param_id:
class_param_id = class_param_id[0]
else:
print(f'класс параметра с id категории изделий - {class_param_id} не существует.')
return 0
cursor.execute('SELECT * FROM product WHERE id_category = ?', (class_param_id,))
products = cursor.fetchall()
if products:
products = products[0]
else:
print(f'изделия с id классом параметра - {class_param_id} не существует.')
return 0
return products
def find_products_in_interval_param(param_id, type_value, start_val, end_val):
if 'int' in type_value.lower():
cursor.execute('SELECT prod_id FROM prod_param WHERE param_id = ? AND int_value >= ? AND int_value <= ?', (param_id, start_val, end_val))
prod_ids = cursor.fetchall()
if prod_ids:
prod_ids = prod_ids
return prod_ids
else:
print(f'изделий с param_id = {param_id}, type_value = {type_value}, start_val = {start_val}, end_val = {end_val} нет в таблице product')
return
if 'real' in type_value.lower():
cursor.execute('SELECT prod_id FROM prod_param WHERE param_id = ? AND real_value >= ? AND real_value <= ?', (param_id, start_val, end_val))
prod_ids = cursor.fetchall()
if prod_ids:
prod_ids = prod_ids
return prod_ids
else:
print(f'изделий с param_id = {param_id}, type_value = {type_value}, start_val = {start_val}, end_val = {end_val} нет в таблице product')
return
##################################### third lab #####################################
##################################### 2-1 lab #####################################
def create_acceptable_component(new_class_id, new_component_id):
# Prevent self-referencing components
if new_class_id == new_component_id:
print("Error: нельзя создать цикл с одинаковыми class_id и component_id!")
return 0 # Failure
try:
# Recursive query to check for cycles in acceptable_components
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 cursor.fetchone():
print(f"Error: добавление пары ({new_class_id}, {new_component_id}) создаёт цикл!")
return 0 # Failure
# Insert the new relationship if no cycle is detected
cursor.execute('''
INSERT INTO acceptable_components (class_id, component_id)
VALUES (?, ?)
''', (new_class_id, new_component_id))
conn.commit()
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
# cycle checking
def check_cyclic_dependency_specif(new_class_id, comp_id):
def fetch_parent_category(cat_id):
cursor.execute("SELECT prod_id FROM prod_position_union WHERE comp_id = ?", (cat_id,))
return cursor.fetchone()[0]
current_id = new_class_id
while current_id is not None:
if current_id == comp_id:
return True
current_id = fetch_parent_category(current_id)
return False
# ???
def create_prod_position_union(new_object_id, new_component_id, new_quantity):
try:
cursor.execute('SELECT id_category FROM product WHERE id = ?', (new_object_id,))
obj_class_id = cursor.fetchone()
if obj_class_id is None:
raise ValueError("Object ID not found")
cursor.execute('SELECT id_category FROM product WHERE id = ?', (new_component_id,))
comp_class_id = cursor.fetchone()
if comp_class_id is None:
raise ValueError("Component ID not found")
cursor.execute('''
SELECT 1
FROM acceptable_components
WHERE class_id = ? AND component_id = ?
''', (obj_class_id[0], comp_class_id[0]))
if cursor.fetchone() is None:
raise ValueError("Invalid composition for the object!")
cursor.execute('''
INSERT INTO prod_position_union (prod_id, comp_id, quantity)
VALUES (?, ?, ?)
''', (new_object_id, new_component_id, new_quantity))
conn.commit()
print('таблица prod_position_union успешно обновлена новым значением.')
return 1 # Success
except Exception as e:
print(f"Error: {e}")
return 0 # Failure
def is_prod_position_union(prod_id, comp_id):
cursor.execute('SELECT 1 FROM prod_position_union WHERE prod_id = ? AND comp_id =?', (prod_id, comp_id,))
res = cursor.fetchone()
if res:
return True
else:
return False
def delete_prod_position_union(prod_id, comp_id):
cursor.execute('''
DELETE FROM prod_position_union
WHERE prod_id = ? AND comp_id = ?
''', (prod_id, comp_id))
deleted_rows = cursor.rowcount
conn.commit()
print(f'в таблице prod_position_union успешно удалено значение - {prod_id, comp_id}')
return 1 if deleted_rows == 1 else 0
def delete_acceptable_component(cl_id, component_cl_id):
deleted_count = 0
try:
# Fetch all products linked to the class_id and component_id
cursor.execute('SELECT id FROM product WHERE id_category = ?', (cl_id,))
obj_ids = [row[0] for row in cursor.fetchall()]
cursor.execute('SELECT id FROM product WHERE id_category = ?', (component_cl_id,))
comp_ids = [row[0] for row in cursor.fetchall()]
# Delete all associated position compositions
for obj_id in obj_ids:
for comp_id in comp_ids:
if is_prod_position_union(obj_id, comp_id):
deleted_count += delete_prod_position_union(obj_id, comp_id)
# Fetch all parents of the component_cl_id (nodes where component_cl_id is a child)
cursor.execute('''
SELECT class_id FROM acceptable_components
WHERE component_id = ?
''', (cl_id,))
parents = [row[0] for row in cursor.fetchall()]
# Fetch all children of the component_cl_id (nodes where component_cl_id is a parent)
cursor.execute('''
SELECT component_id FROM acceptable_components
WHERE class_id = ?
''', (component_cl_id,))
children = [row[0] for row in cursor.fetchall()]
# Delete the specified relationship
cursor.execute('''
DELETE FROM acceptable_components
WHERE class_id = ? AND component_id = ?
''', (cl_id, component_cl_id))
# Connect parents of cl_id to children of component_cl_id
for parent in parents:
for child in children:
# Check if the relationship already exists
cursor.execute('''
SELECT 1 FROM acceptable_components
WHERE class_id = ? AND component_id = ?
''', (parent, child))
if cursor.fetchone() is None:
cursor.execute('''
INSERT INTO acceptable_components (class_id, component_id)
VALUES (?, ?)
''', (parent, child))
conn.commit()
print(f'из класса с id - {cl_id} успешно удален компонент с id - {component_cl_id}, соединены родители и дети.')
return deleted_count
except Exception as e:
print(f"Error: {e}")
return deleted_count
def edit_prod_position_union_quantity(obj_id, comp_id, new_quantity):
cursor.execute('''
UPDATE prod_position_union
SET quantity = ?
WHERE prod_id = ? AND comp_id = ?
''', (new_quantity, obj_id, comp_id))
updated_rows = cursor.rowcount
conn.commit()
print(f"значение позиции {(obj_id, comp_id)} установлено в {new_quantity}")
return 1 if updated_rows == 1 else 0
def inherit_acceptable_components(cl_id):
inserted_count = 0
try:
cursor.execute('SELECT id_parent FROM terminal_classifier WHERE id = ?', (cl_id,))
parent_cl_id = cursor.fetchone()
if parent_cl_id is None:
raise ValueError("Parent class ID not found")
cursor.execute('''
SELECT component_id FROM acceptable_components
WHERE class_id = ?
''', (parent_cl_id[0],))
components = cursor.fetchall()
# Insert acceptable components for the child class
for (component_id,) in components:
cursor.execute('''
INSERT OR IGNORE INTO acceptable_components (class_id, component_id)
VALUES (?, ?)
Соседние файлы в папке 4