import sqlite3 from loguru import logger as log from utils.slugify import slugify def init_database(db_name='pipe_store.db'): conn = sqlite3.connect(db_name) cursor = conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS categories ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, description TEXT, parent_id INTEGER, image_path TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (parent_id) REFERENCES categories (id) ) ''') cursor.execute(''' CREATE TABLE IF NOT EXISTS products ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, category_id INTEGER NOT NULL, diameter INTEGER, wall_thickness REAL, length INTEGER, color TEXT, application_type TEXT, -- внутренняя/наружная stiffness_class TEXT, -- SN4, SN2 и т.д. image_path TEXT, slug TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (category_id) REFERENCES categories (id) ) ''') cursor.execute(''' CREATE TABLE IF NOT EXISTS filters ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, filter_key TEXT NOT NULL UNIQUE, -- ключ для фильтрации filter_type TEXT DEFAULT 'single' -- 'single' или 'multiple' ) ''') cursor.execute(''' CREATE TABLE IF NOT EXISTS product_filters ( id INTEGER PRIMARY KEY AUTOINCREMENT, product_id INTEGER NOT NULL, filter_key TEXT NOT NULL, value TEXT NOT NULL, FOREIGN KEY (product_id) REFERENCES products (id), FOREIGN KEY (filter_key) REFERENCES filters (filter_key), UNIQUE(product_id, filter_key) ) ''') cursor.execute('CREATE INDEX IF NOT EXISTS idx_products_category ON products(category_id)') cursor.execute('CREATE INDEX IF NOT EXISTS idx_products_diameter ON products(diameter)') cursor.execute('CREATE INDEX IF NOT EXISTS idx_products_length ON products(length)') cursor.execute('CREATE INDEX IF NOT EXISTS idx_product_filters_key_value ON product_filters(filter_key, value)') # Миграция: добавляем колонку slug, если её нет cursor.execute("PRAGMA table_info(products)") columns = {row[1] for row in cursor.fetchall()} if 'slug' not in columns: cursor.execute("ALTER TABLE products ADD COLUMN slug TEXT") log.info("Migration: added 'slug' column to products") # Миграция: переименовываем full_name → name cursor.execute("PRAGMA table_info(products)") columns = {row[1] for row in cursor.fetchall()} if 'full_name' in columns and 'name' not in columns: cursor.executescript(''' PRAGMA foreign_keys=OFF; CREATE TABLE products_new ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, category_id INTEGER NOT NULL, diameter INTEGER, wall_thickness REAL, length INTEGER, color TEXT, application_type TEXT, stiffness_class TEXT, image_path TEXT, slug TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (category_id) REFERENCES categories (id) ); INSERT INTO products_new (id, name, description, category_id, diameter, wall_thickness, length, color, application_type, stiffness_class, image_path, slug, created_at) SELECT id, full_name, description, category_id, diameter, wall_thickness, length, color, application_type, stiffness_class, image_path, slug, created_at FROM products; DROP TABLE products; ALTER TABLE products_new RENAME TO products; CREATE INDEX IF NOT EXISTS idx_products_category ON products(category_id); CREATE INDEX IF NOT EXISTS idx_products_diameter ON products(diameter); CREATE INDEX IF NOT EXISTS idx_products_length ON products(length); ''') log.info("Migrated products table: renamed 'full_name' → 'name'") # Миграция: заполняем slug для старых товаров cursor.execute(""" SELECT p.id, p.name, p.diameter, p.wall_thickness, p.length, p.stiffness_class, p.application_type, pf.value as fitting_type FROM products p LEFT JOIN product_filters pf ON pf.product_id = p.id AND pf.filter_key = 'fitting_type' WHERE p.slug IS NULL OR p.slug = '' """) rows = cursor.fetchall() for row in rows: id_, name, diameter, wall_thickness, length, stiffness_class, application_type, fitting_type = row if fitting_type: slug_source = name else: slug_parts = [name] if stiffness_class: slug_parts.append(stiffness_class) if diameter: slug_parts.append(f"d{diameter}") if wall_thickness: slug_parts.append(f"stenka{int(wall_thickness)}") if length and length > 0: slug_parts.append(f"l{length}") slug_source = " ".join(slug_parts) slug = slugify(slug_source) cursor.execute("UPDATE products SET slug = ? WHERE id = ?", (slug, id_)) log.info(f"Backfill slug for product {id_}: {slug}") conn.commit() conn.close() log.success("База данных успешно инициализирована!")