# database_init.py """ Скрипт инициализации базы данных с исправлением ошибки типа данных """ import argparse import sys import os from app.database import db import bcrypt def parse_arguments(): """Парсинг аргументов командной строки""" parser = argparse.ArgumentParser(description='Инициализация базы данных MasterPol') parser.add_argument('--host', default='localhost', help='Хост PostgreSQL') parser.add_argument('--port', default='5432', help='Порт PostgreSQL') parser.add_argument('--database', default='masterpol', help='Имя базы данных') parser.add_argument('--username', default='postgres', help='Имя пользователя PostgreSQL') parser.add_argument('--password', required=True, help='Пароль пользователя PostgreSQL') return parser.parse_args() def initialize_database(db_url): """Инициализация структуры базы данных с тестовыми данными""" # Устанавливаем URL базы данных os.environ['DATABASE_URL'] = db_url # Удаляем существующие таблицы (для чистой инициализации) drop_tables = """ DROP TABLE IF EXISTS sales CASCADE; DROP TABLE IF EXISTS partners CASCADE; DROP TABLE IF EXISTS managers CASCADE; """ # Создание таблицы партнеров с правильным типом для rating partners_table = """ CREATE TABLE IF NOT EXISTS partners ( partner_id SERIAL PRIMARY KEY, partner_type VARCHAR(50), company_name VARCHAR(255) NOT NULL, legal_address TEXT, inn VARCHAR(20) UNIQUE NOT NULL, director_name VARCHAR(255), phone VARCHAR(50), email VARCHAR(255), rating INTEGER NOT NULL DEFAULT 0 CHECK (rating >= 0 AND rating <= 100), sales_locations TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """ # Создание таблицы продаж sales_table = """ CREATE TABLE IF NOT EXISTS sales ( sale_id SERIAL PRIMARY KEY, partner_id INTEGER NOT NULL REFERENCES partners(partner_id) ON DELETE CASCADE, product_name VARCHAR(255) NOT NULL, quantity DECIMAL(15,2) NOT NULL, sale_date DATE NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """ # Создание таблицы менеджеров managers_table = """ CREATE TABLE IF NOT EXISTS managers ( manager_id SERIAL PRIMARY KEY, username VARCHAR(100) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, full_name VARCHAR(255) NOT NULL, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """ try: # Удаляем существующие таблицы try: db.execute_query(drop_tables) print("✅ Существующие таблицы удалены") except Exception as e: print(f"ℹ️ Таблицы для удаления не найдены: {e}") # Создание таблиц db.execute_query(partners_table) db.execute_query(sales_table) db.execute_query(managers_table) print("✅ База данных успешно инициализирована") # Создание тестового менеджера password = "pass123" hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') db.execute_query(""" INSERT INTO managers (username, password_hash, full_name) VALUES ('manager', %s, 'Тестовый Менеджер') ON CONFLICT (username) DO NOTHING """, (hashed_password,)) print("✅ Тестовый пользователь создан (manager/pass123)") # Добавление тестовых партнеров test_partners = [ { 'partner_type': 'distributor', 'company_name': 'ООО "Ромашка"', 'legal_address': 'г. Москва, ул. Ленина, д. 1', 'inn': '1234567890', 'director_name': 'Иванов Иван Иванович', 'phone': '+79991234567', 'email': 'info@romashka.ru', 'rating': 85, # INTEGER значение от 0 до 100 'sales_locations': 'Москва, Санкт-Петербург' }, { 'partner_type': 'retail', 'company_name': 'ИП Петров', 'legal_address': 'г. Санкт-Петербург, Невский пр., д. 100', 'inn': '0987654321', 'director_name': 'Петров Петр Петрович', 'phone': '+79998765432', 'email': 'petrov@mail.ru', 'rating': 72, # INTEGER значение от 0 до 100 'sales_locations': 'Санкт-Петербург' } ] for partner in test_partners: db.execute_query(""" INSERT INTO partners (partner_type, company_name, legal_address, inn, director_name, phone, email, rating, sales_locations) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) """, ( partner['partner_type'], partner['company_name'], partner['legal_address'], partner['inn'], partner['director_name'], partner['phone'], partner['email'], partner['rating'], partner['sales_locations'] )) print("✅ Тестовые партнеры добавлены") # Добавление тестовых продаж test_sales = [ (1, 'Продукт А', 150.50, '2024-01-15'), (1, 'Продукт Б', 75.25, '2024-01-16'), (2, 'Продукт В', 200.00, '2024-01-17'), (1, 'Продукт А', 100.00, '2024-01-18') ] for sale in test_sales: db.execute_query(""" INSERT INTO sales (partner_id, product_name, quantity, sale_date) VALUES (%s, %s, %s, %s) """, sale) print("✅ Тестовые продажи добавлены") # Проверяем, что данные корректно добавлены partners_count = db.execute_query("SELECT COUNT(*) as count FROM partners")[0]['count'] sales_count = db.execute_query("SELECT COUNT(*) as count FROM sales")[0]['count'] managers_count = db.execute_query("SELECT COUNT(*) as count FROM managers")[0]['count'] print(f"📊 Статистика базы данных:") print(f" - Партнеров: {partners_count}") print(f" - Продаж: {sales_count}") print(f" - Менеджеров: {managers_count}") return True except Exception as e: print(f"❌ Ошибка инициализации базы данных: {e}") import traceback traceback.print_exc() return False def main(): """Основная функция""" args = parse_arguments() # Формируем URL подключения db_url = f"postgresql://{args.username}:{args.password}@{args.host}:{args.port}/{args.database}" print(f"🔄 Подключение к базе данных: {args.database} на {args.host}:{args.port}") success = initialize_database(db_url) if success: print("🎉 Инициализация базы данных завершена успешно!") sys.exit(0) else: print("💥 Инициализация базы данных завершена с ошибками!") sys.exit(1) if __name__ == "__main__": main()