From 6863cf86fab64652ed6fc245b7ac5fe11d84d7de Mon Sep 17 00:00:00 2001 From: Kirill Date: Sun, 23 Nov 2025 21:44:00 +0300 Subject: [PATCH] fix(DataBase): Recreate Initializing of structure --- db/InitializeDBData.py | 383 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 339 insertions(+), 44 deletions(-) diff --git a/db/InitializeDBData.py b/db/InitializeDBData.py index 5c4b3db..04b778e 100644 --- a/db/InitializeDBData.py +++ b/db/InitializeDBData.py @@ -1,60 +1,355 @@ import sqlite3 -import json from loguru import logger as log def add_products(): conn = sqlite3.connect('products.db') cursor = conn.cursor() - + + # Проверяем существование данных cursor.execute('SELECT COUNT(*) FROM Category') category_count = cursor.fetchone()[0] if category_count > 0: - log.info("Категории уже существуют в базе данных, пропускаем добавление") + log.info("Данные уже существуют в базе данных, пропускаем добавление") conn.close() return - - categories_data = [ - ('Внутренняя канализация', [["Диаметр", "string"], ["Длина", "string"], ["Толщина стенки", "string"], ["Цвет", "string"]]), - ('Наружная канализация', [["Диаметр", "string"], ["Длина", "string"], ["Толщина стенки", "string"], ["Класс жесткости", "string"], ["Цвет", "string"]]) - ] - - category_ids = {} - for name, atributes in categories_data: - atributes_json = json.dumps(atributes) - cursor.execute( - 'INSERT INTO Category (name, atributes) VALUES (?, ?)', - (name, atributes_json) - ) - category_ids[name] = cursor.lastrowid - log.info(f"Добавлена категория: {name}") - + + # Данные из прайс-листа products_data = [ - ('Труба ПВХ 110x2,25000', 'Труба ПВХ для ВНУТРЕННЕЙ канализации (цвет серый), со сплошной внутренней стенкой толщиной 2,2 мм. Размер: 110x2,25000. Количество в упаковке: 4 шт.', 'images/internal_110_1.jpg', '110x2,25000', 'Внутренняя канализация'), - ('Труба ПВХ 110x2,25000', 'Труба ПВХ для ВНУТРЕННЕЙ канализации (цвет серый), со сплошной внутренней стенкой толщиной 2,2 мм. Размер: 110x2,25000. Количество в упаковке: 4 шт.', 'images/internal_110_2.jpg', '110x2,25000', 'Внутренняя канализация'), - ('Труба ПВХ 110x2,25000', 'Труба ПВХ для ВНУТРЕННЕЙ канализации (цвет серый), со сплошной внутренней стенкой толщиной 2,2 мм. Размер: 110x2,25000. Количество в упаковке: 4 шт.', 'images/internal_110_3.jpg', '110x2,25000', 'Внутренняя канализация'), - ('Труба ПВХ 110x2,25000', 'Труба ПВХ для ВНУТРЕННЕЙ канализации (цвет серый), со сплошной внутренней стенкой толщиной 2,2 мм. Размер: 110x2,25000. Количество в упаковке: 4 шт.', 'images/internal_110_4.jpg', '110x2,25000', 'Внутренняя канализация'), - ('Труба ПВХ 110x2,25000', 'Труба ПВХ для ВНУТРЕННЕЙ канализации (цвет серый), со сплошной внутренней стенкой толщиной 2,2 мм. Размер: 110x2,25000. Количество в упаковке: 4 шт.', 'images/internal_110_5.jpg', '110x2,25000', 'Внутренняя канализация'), - ('Труба ПВХ 110x3,25000', 'Труба ПВХ для НАРУЖНОЙ канализации (цвет коричнево-оранжевый), со сплошной внутренней стенкой, класс жесткости 8мм. Размер: 110x3,25000. Количество в упаковке: 4 шт.', 'images/external_110_1.jpg', '110x3,25000', 'Наружная канализация'), - ('Труба ПВХ 110x3,25000', 'Труба ПВХ для НАРУЖНОЙ канализации (цвет коричнево-оранжевый), со сплошной внутренней стенкой, класс жесткости 8мм. Размер: 110x3,25000. Количество в упаковке: 4 шт.', 'images/external_110_2.jpg', '110x3,25000', 'Наружная канализация'), - ('Труба ПВХ 110x3,25000', 'Труба ПВХ для НАРУЖНОЙ канализации (цвет коричнево-оранжевый), со сплошной внутренней стенкой, класс жесткости 8мм. Размер: 110x3,25000. Количество в упаковке: 4 шт.', 'images/external_110_3.jpg', '110x3,25000', 'Наружная канализация'), - ('Труба ПВХ 110x3,25000', 'Труба ПВХ для НАРУЖНОЙ канализации (цвет коричнево-оранжевый), со сплошной внутренней стенкой, класс жесткости 8мм. Размер: 110x3,25000. Количество в упаковке: 4 шт.', 'images/external_110_4.jpg', '110x3,25000', 'Наружная канализация'), - ('Труба ПВХ 110x3,25000', 'Труба ПВХ для НАРУЖНОЙ канализации (цвет коричнево-оранжевый), со сплошной внутренней стенкой, класс жесткости 8мм. Размер: 110x3,25000. Количество в упаковке: 4 шт.', 'images/external_110_5.jpg', '110x3,25000', 'Наружная канализация'), - ('Труба ПВХ 160x3,50000', 'Труба ПВХ для НАРУЖНОЙ канализации (цвет коричнево-оранжевый), со сплошной внутренней стенкой, класс жесткости 8мм. Размер: 160x3,50000. Количество в упаковке: 2 шт.', 'images/external_160_1.jpg', '160x3,50000', 'Наружная канализация'), - ('Труба ПВХ 160x3,50000', 'Труба ПВХ для НАРУЖНОЙ канализации (цвет коричнево-оранжевый), со сплошной внутренней стенкой, класс жесткости 8мм. Размер: 160x3,50000. Количество в упаковке: 2 шт.', 'images/external_160_2.jpg', '160x3,50000', 'Наружная канализация'), - ('Труба ПВХ 160x3,50000', 'Труба ПВХ для НАРУЖНОЙ канализации (цвет коричнево-оранжевый), со сплошной внутренней стенкой, класс жесткости 8мм. Размер: 160x3,50000. Количество в упаковке: 2 шт.', 'images/external_160_3.jpg', '160x3,50000', 'Наружная канализация'), + { + 'category_name': 'Труба ПВХ для ВНУТРЕННЕЙ канализации', + 'category_description': 'цвет серый, со сплошной внутренней стенкой толщиной 2,2 мм', + 'category_image': 'images/category_internal.jpg', + 'products': [ + { + 'name': 'Труба ПВХ 110x2,2 2500мм', + 'spec': '110x2,25000', + 'image_path': 'images/internal_110_1.jpg', + 'price': 98.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '2.2 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'серый', + 'Назначение': 'внутренняя канализация' + } + }, + { + 'name': 'Труба ПВХ 110x2,2 2500мм', + 'spec': '110x2,25000', + 'image_path': 'images/internal_110_2.jpg', + 'price': 165.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '2.2 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'серый', + 'Назначение': 'внутренняя канализация' + } + }, + { + 'name': 'Труба ПВХ 110x2,2 2500мм', + 'spec': '110x2,25000', + 'image_path': 'images/internal_110_3.jpg', + 'price': 236.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '2.2 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'серый', + 'Назначение': 'внутренняя канализация' + } + }, + { + 'name': 'Труба ПВХ 110x2,2 2500мм', + 'spec': '110x2,25000', + 'image_path': 'images/internal_110_4.jpg', + 'price': 284.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '2.2 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'серый', + 'Назначение': 'внутренняя канализация' + } + }, + { + 'name': 'Труба ПВХ 110x2,2 2500мм', + 'spec': '110x2,25000', + 'image_path': 'images/internal_110_5.jpg', + 'price': 426.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '2.2 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'серый', + 'Назначение': 'внутренняя канализация' + } + } + ] + }, + { + 'category_name': 'Труба ПВХ для НАРУЖНОЙ канализации', + 'category_description': 'цвет коричнево-оранжевый, со сплошной внутренней стенкой, класс жесткости 8мм', + 'category_image': 'images/category_external.jpg', + 'products': [ + { + 'name': 'Труба ПВХ 110x3,0 2500мм', + 'spec': '110x3,25000', + 'image_path': 'images/external_110_1.jpg', + 'price': 125.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '3.0 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'коричнево-оранжевый', + 'Назначение': 'наружная канализация', + 'Класс жесткости': '8 мм' + } + }, + { + 'name': 'Труба ПВХ 110x3,0 2500мм', + 'spec': '110x3,25000', + 'image_path': 'images/external_110_2.jpg', + 'price': 220.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '3.0 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'коричнево-оранжевый', + 'Назначение': 'наружная канализация', + 'Класс жесткости': '8 мм' + } + }, + { + 'name': 'Труба ПВХ 110x3,0 2500мм', + 'spec': '110x3,25000', + 'image_path': 'images/external_110_3.jpg', + 'price': 380.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '3.0 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'коричнево-оранжевый', + 'Назначение': 'наружная канализация', + 'Класс жесткости': '8 мм' + } + }, + { + 'name': 'Труба ПВХ 110x3,0 2500мм', + 'spec': '110x3,25000', + 'image_path': 'images/external_110_4.jpg', + 'price': 585.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '3.0 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'коричнево-оранжевый', + 'Назначение': 'наружная канализация', + 'Класс жесткости': '8 мм' + } + }, + { + 'name': 'Труба ПВХ 110x3,0 2500мм', + 'spec': '110x3,25000', + 'image_path': 'images/external_110_5.jpg', + 'price': 780.00, + 'quantity_per_package': 4, + 'params': { + 'Диаметр': '110 мм', + 'Толщина стенки': '3.0 мм', + 'Длина': '2500 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'коричнево-оранжевый', + 'Назначение': 'наружная канализация', + 'Класс жесткости': '8 мм' + } + }, + { + 'name': 'Труба ПВХ 160x3,0 5000мм SM 2', + 'spec': '160x3,50000 SM 2', + 'image_path': 'images/external_160_1.jpg', + 'price': 398.00, + 'quantity_per_package': 2, + 'params': { + 'Диаметр': '160 мм', + 'Толщина стенки': '3.0 мм', + 'Длина': '5000 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'коричнево-оранжевый', + 'Назначение': 'наружная канализация', + 'Класс жесткости': '8 мм', + 'Маркировка': 'SM 2' + } + }, + { + 'name': 'Труба ПВХ 160x3,0 5000мм SM 2', + 'spec': '160x3,50000 SM 2', + 'image_path': 'images/external_160_2.jpg', + 'price': 724.00, + 'quantity_per_package': 2, + 'params': { + 'Диаметр': '160 мм', + 'Толщина стенки': '3.0 мм', + 'Длина': '5000 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'коричнево-оранжевый', + 'Назначение': 'наружная канализация', + 'Класс жесткости': '8 мм', + 'Маркировка': 'SM 2' + } + }, + { + 'name': 'Труба ПВХ 160x3,0 5000мм SM 2', + 'spec': '160x3,50000 SM 2', + 'image_path': 'images/external_160_3.jpg', + 'price': 1068.00, + 'quantity_per_package': 2, + 'params': { + 'Диаметр': '160 мм', + 'Толщина стенки': '3.0 мм', + 'Длина': '5000 мм', + 'Тип': 'со сплошной внутренней стенкой', + 'Цвет': 'коричнево-оранжевый', + 'Назначение': 'наружная канализация', + 'Класс жесткости': '8 мм', + 'Маркировка': 'SM 2' + } + } + ] + } ] - - for name, desc, image_path, size, category_name in products_data: - cursor.execute('SELECT id FROM Category WHERE name = ?', (category_name,)) - category_row = cursor.fetchone() - if category_row: - category_id = category_row[0] - cursor.execute( - 'INSERT INTO Product (name, category, desc, image_path, size) VALUES (?, ?, ?, ?, ?)', - (name, category_id, desc, image_path, size) - ) - + + # Собираем все уникальные значения Val + all_vals = {} + val_counter = 1 + + # Собираем все уникальные параметры + all_params = {} + param_counter = 1 + + # Сначала собираем все уникальные значения + for category_data in products_data: + # Собираем значения из params продуктов + for product in category_data['products']: + for param_value in product['params'].values(): + if param_value not in all_vals: + all_vals[param_value] = val_counter + val_counter += 1 + + # Добавляем значения в таблицу Val + for val_text, val_id in all_vals.items(): + cursor.execute('INSERT INTO Val (id, val) VALUES (?, ?)', (val_id, val_text)) + log.info(f"Добавлено значение: {val_text} (id: {val_id})") + + # Собираем все уникальные параметры (Param) + for category_data in products_data: + for product in category_data['products']: + for param_name, param_value in product['params'].items(): + key = f"{param_name}_{param_value}" + if key not in all_params: + val_id = all_vals[param_value] + all_params[key] = {'id': param_counter, 'name': param_name, 'val_id': val_id} + param_counter += 1 + + # Добавляем параметры в таблицу Param + for key, param in all_params.items(): + cursor.execute('INSERT INTO Param (id, name, val) VALUES (?, ?, ?)', + (param['id'], param['name'], param_value)) + log.info(f"Добавлен параметр: {param['name']} = {param_value}") + + # Добавляем категории, продукты и связи + category_counter = 1 + product_counter = 1 + + for category_data in products_data: + # Создаем CParams для категории (основные характеристики категории) + cparams_ids = [] + + # Основные параметры категории из описания + category_params = { + 'Назначение': 'внутренняя канализация' if 'ВНУТРЕННЕЙ' in category_data['category_name'] else 'наружная канализация', + 'Цвет': 'серый' if 'ВНУТРЕННЕЙ' in category_data['category_name'] else 'коричнево-оранжевый', + 'Тип стенки': 'сплошная внутренняя' + } + + if 'ВНУТРЕННЕЙ' in category_data['category_name']: + category_params['Толщина стенки'] = '2.2 мм' + else: + category_params['Класс жесткости'] = '8 мм' + + for cparam_name, cparam_value in category_params.items(): + if cparam_value in all_vals: + val_id = all_vals[cparam_value] + cursor.execute('INSERT INTO CParams (name, val_id) VALUES (?, ?)', + (cparam_name, val_id)) + cparams_ids.append(cursor.lastrowid) + log.info(f"Добавлен категорийный параметр: {cparam_name} = {cparam_value}") + + # Основной c_params_id для категории (берем первый) + main_cparams_id = cparams_ids[0] if cparams_ids else None + + # Добавляем категорию (пока без prod_id) + cursor.execute(''' + INSERT INTO Category (name, prod_id, image_path, c_params_id) + VALUES (?, ?, ?, ?) + ''', (category_data['category_name'], None, + category_data['category_image'], main_cparams_id)) + + category_id = cursor.lastrowid + + # Добавляем продукты категории + first_product_id = None + for product in category_data['products']: + # Добавляем продукт + cursor.execute('INSERT INTO Product (name, image_path) VALUES (?, ?)', + (product['name'], product['image_path'])) + product_id = cursor.lastrowid + + # Сохраняем ID первого продукта для связи с категорией + if first_product_id is None: + first_product_id = product_id + + # Добавляем связи продукт-параметры + for param_name, param_value in product['params'].items(): + param_key = f"{param_name}_{param_value}" + if param_key in all_params: + param_id = all_params[param_key]['id'] + cursor.execute('INSERT INTO Product_Param (product_id, param_id) VALUES (?, ?)', + (product_id, param_id)) + + product_counter += 1 + log.info(f"Добавлен продукт: {product['name']} (цена: {product['price']} руб., упаковка: {product['quantity_per_package']} шт.)") + + # Обновляем prod_id для категории (первый продукт как представитель) + if first_product_id: + cursor.execute('UPDATE Category SET prod_id = ? WHERE id = ?', + (first_product_id, category_id)) + + category_counter += 1 + log.info(f"Добавлена категория: {category_data['category_name']}") + conn.commit() conn.close() - log.info(f"Добавлено {len(products_data)} товаров в базу данных!") + + total_products = product_counter - 1 + total_categories = category_counter - 1 + log.info(f"Успешно добавлено {total_products} товаров и {total_categories} категорий в базу данных!")