420 lines
18 KiB
Python
420 lines
18 KiB
Python
import sqlite3
|
||
import pandas as pd
|
||
import os
|
||
from database import get_db, create_tables
|
||
|
||
|
||
def reset_database():
|
||
"""Полностью пересоздает базу данных"""
|
||
if os.path.exists('partners.db'):
|
||
os.remove('partners.db')
|
||
create_tables()
|
||
print("✅ База данных пересоздана")
|
||
|
||
|
||
def import_data_from_files():
|
||
"""Загружает данные из Excel файлов в базу данных"""
|
||
try:
|
||
# Сначала пересоздаем базу данных
|
||
reset_database()
|
||
|
||
print("\n📁 Введите имена файлов (или нажмите Enter для использования файлов по умолчанию):")
|
||
|
||
partners_file = input("Файл с партнерами (Partners_import.xlsx): ").strip()
|
||
if not partners_file:
|
||
partners_file = "data/Partners_import.xlsx"
|
||
|
||
product_types_file = input("Файл с типами товаров (Product_types_import.xlsx): ").strip()
|
||
if not product_types_file:
|
||
product_types_file = "data/Product_types_import.xlsx"
|
||
|
||
products_file = input("Файл с товарами (Products_import.xlsx): ").strip()
|
||
if not products_file:
|
||
products_file = "data/Products_import.xlsx"
|
||
|
||
orders_file = input("Файл с заказами (Orders_import.xlsx): ").strip()
|
||
if not orders_file:
|
||
orders_file = "data/Orders_import.xlsx"
|
||
|
||
order_items_file = input("Файл с позициями заказов (Order_items_import.xlsx): ").strip()
|
||
if not order_items_file:
|
||
order_items_file = "data/Order_items_import.xlsx"
|
||
|
||
# Проверяем существование файлов
|
||
files_to_check = [partners_file, product_types_file, products_file, orders_file, order_items_file]
|
||
for file in files_to_check:
|
||
if not os.path.exists(file):
|
||
print(f"❌ Файл не найден: {file}")
|
||
return
|
||
|
||
with get_db() as conn:
|
||
# Включаем поддержку внешних ключей
|
||
conn.execute("PRAGMA foreign_keys = ON")
|
||
|
||
# 1. Загрузка типов товаров
|
||
print("\n1. 📦 Загрузка типов товаров...")
|
||
types_df = pd.read_excel(product_types_file)
|
||
|
||
type_name_col = None
|
||
for col in ['type_name', 'Тип товара', 'name', 'название']:
|
||
if col in types_df.columns:
|
||
type_name_col = col
|
||
break
|
||
|
||
description_col = None
|
||
for col in ['description', 'Описание', 'desc']:
|
||
if col in types_df.columns:
|
||
description_col = col
|
||
break
|
||
|
||
if not type_name_col:
|
||
print("❌ Не найден столбец с названием типа товара")
|
||
return
|
||
|
||
type_count = 0
|
||
for _, row in types_df.iterrows():
|
||
try:
|
||
type_name = str(row[type_name_col])
|
||
description = str(row[description_col]) if description_col and pd.notna(
|
||
row.get(description_col)) else ''
|
||
|
||
conn.execute('''
|
||
INSERT INTO product_types (type_name, description)
|
||
VALUES (?, ?)
|
||
''', (type_name, description))
|
||
type_count += 1
|
||
except Exception as e:
|
||
print(f" ⚠️ Ошибка при загрузке типа товара: {e}")
|
||
continue
|
||
print(f" Загружено {type_count} типов товаров")
|
||
|
||
# 2. Загрузка партнеров
|
||
print("2. 🏢 Загрузка партнеров...")
|
||
partners_df = pd.read_excel(partners_file)
|
||
|
||
partner_cols = {}
|
||
|
||
for col in ['partner_name', 'Наименование партнера', 'name', 'supplier_name', 'название']:
|
||
if col in partners_df.columns:
|
||
partner_cols['name'] = col
|
||
break
|
||
|
||
for col in ['director', 'Директор']:
|
||
if col in partners_df.columns:
|
||
partner_cols['director'] = col
|
||
break
|
||
|
||
for col in ['email', 'Электронная почта', 'почта']:
|
||
if col in partners_df.columns:
|
||
partner_cols['email'] = col
|
||
break
|
||
|
||
for col in ['phone', 'Телефон']:
|
||
if col in partners_df.columns:
|
||
partner_cols['phone'] = col
|
||
break
|
||
|
||
for col in ['legal_address', 'Юридический адрес', 'address', 'адрес']:
|
||
if col in partners_df.columns:
|
||
partner_cols['address'] = col
|
||
break
|
||
|
||
for col in ['inn', 'ИНН']:
|
||
if col in partners_df.columns:
|
||
partner_cols['inn'] = col
|
||
break
|
||
|
||
for col in ['rating', 'Рейтинг']:
|
||
if col in partners_df.columns:
|
||
partner_cols['rating'] = col
|
||
break
|
||
|
||
if 'name' not in partner_cols or 'email' not in partner_cols or 'inn' not in partner_cols:
|
||
print("❌ Не найдены обязательные колонки для партнеров")
|
||
print(" Доступные колонки:", list(partners_df.columns))
|
||
return
|
||
|
||
partner_count = 0
|
||
for _, row in partners_df.iterrows():
|
||
try:
|
||
name = str(row[partner_cols['name']])
|
||
email = str(row[partner_cols['email']])
|
||
inn = str(row[partner_cols['inn']])
|
||
|
||
director = str(row.get(partner_cols.get('director'), '')) if 'director' in partner_cols else ''
|
||
phone = str(row.get(partner_cols.get('phone'), '')) if 'phone' in partner_cols else ''
|
||
address = str(row.get(partner_cols.get('address'), '')) if 'address' in partner_cols else ''
|
||
|
||
rating_val = row.get(partner_cols.get('rating'), 0) if 'rating' in partner_cols else 0
|
||
try:
|
||
rating = float(rating_val) if rating_val else 0.0
|
||
except:
|
||
rating = 0.0
|
||
|
||
conn.execute('''
|
||
INSERT INTO partners
|
||
(name, director, email, phone, legal_address, inn, rating)
|
||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||
''', (name, director, email, phone, address, inn, rating))
|
||
partner_count += 1
|
||
except Exception as e:
|
||
print(f" ⚠️ Ошибка при загрузке партнера: {e}")
|
||
continue
|
||
|
||
print(f" Загружено {partner_count} партнеров")
|
||
|
||
# 3. Загрузка товаров
|
||
print("3. 📝 Загрузка товаров...")
|
||
products_df = pd.read_excel(products_file)
|
||
|
||
print(" Доступные колонки в файле товаров:", list(products_df.columns))
|
||
|
||
product_cols = {}
|
||
|
||
for col in ['product_type_id', 'ID типа', 'type_id', 'тип_id']:
|
||
if col in products_df.columns:
|
||
product_cols['type_id'] = col
|
||
break
|
||
|
||
for col in ['product_name', 'Наименование', 'name', 'товар']:
|
||
if col in products_df.columns:
|
||
product_cols['name'] = col
|
||
break
|
||
|
||
for col in ['article', 'Артикул', 'артикул']:
|
||
if col in products_df.columns:
|
||
product_cols['article'] = col
|
||
break
|
||
|
||
for col in ['min_price', 'Минимальная цена', 'price', 'цена', 'min_partner_price']:
|
||
if col in products_df.columns:
|
||
product_cols['price'] = col
|
||
break
|
||
|
||
for col in ['stock_quantity', 'Остаток', 'stock', 'quantity_in_stock', 'количество']:
|
||
if col in products_df.columns:
|
||
product_cols['stock'] = col
|
||
break
|
||
|
||
missing_cols = []
|
||
if 'type_id' not in product_cols:
|
||
missing_cols.append('ID типа товара (product_type_id)')
|
||
if 'name' not in product_cols:
|
||
missing_cols.append('Название товара (product_name)')
|
||
if 'article' not in product_cols:
|
||
missing_cols.append('Артикул (article)')
|
||
if 'price' not in product_cols:
|
||
missing_cols.append('Цена (min_price)')
|
||
|
||
if missing_cols:
|
||
print(f"❌ Не найдены обязательные колонки: {', '.join(missing_cols)}")
|
||
return
|
||
|
||
# Получаем все существующие ID типов товаров
|
||
existing_type_ids = [row[0] for row in conn.execute('SELECT id FROM product_types').fetchall()]
|
||
print(f" Существующие ID типов товаров: {existing_type_ids}")
|
||
|
||
products_loaded = 0
|
||
for index, row in products_df.iterrows():
|
||
try:
|
||
product_type_id = int(row[product_cols['type_id']])
|
||
product_name = str(row[product_cols['name']])
|
||
article = str(row[product_cols['article']])
|
||
|
||
price_val = row[product_cols['price']]
|
||
if pd.isna(price_val):
|
||
print(f" ⚠️ Пропуск товара {product_name}: пустая цена")
|
||
continue
|
||
price = float(price_val)
|
||
|
||
stock_val = row.get(product_cols.get('stock'), 0) if 'stock' in product_cols else 0
|
||
if pd.isna(stock_val):
|
||
stock = 0
|
||
else:
|
||
stock = int(stock_val)
|
||
|
||
if price <= 0:
|
||
print(f" ⚠️ Некорректная цена для товара {product_name}: {price}")
|
||
continue
|
||
|
||
if product_type_id not in existing_type_ids:
|
||
print(f" ⚠️ Тип товара с ID {product_type_id} не найден. Доступные ID: {existing_type_ids}")
|
||
continue
|
||
|
||
conn.execute('''
|
||
INSERT INTO products
|
||
(product_type_id, product_name, article, min_partner_price, quantity_in_stock)
|
||
VALUES (?, ?, ?, ?, ?)
|
||
''', (product_type_id, product_name, article, price, max(0, stock)))
|
||
products_loaded += 1
|
||
print(f" ✓ Загружен товар: {product_name} (ID типа: {product_type_id})")
|
||
|
||
except Exception as e:
|
||
print(f" ⚠️ Ошибка при загрузке товара в строке {index + 2}: {e}")
|
||
continue
|
||
|
||
print(f" Загружено {products_loaded} товаров")
|
||
|
||
# 4. Загрузка заказов
|
||
print("4. 📋 Загрузка заказов...")
|
||
orders_df = pd.read_excel(orders_file)
|
||
|
||
print(" Доступные колонки в файле заказов:", list(orders_df.columns))
|
||
|
||
order_cols = {}
|
||
|
||
for col in ['partner_id', 'ID партнера', 'partner', 'партнер']:
|
||
if col in orders_df.columns:
|
||
order_cols['partner_id'] = col
|
||
break
|
||
|
||
for col in ['order_date', 'Дата заказа', 'date', 'дата']:
|
||
if col in orders_df.columns:
|
||
order_cols['date'] = col
|
||
break
|
||
|
||
for col in ['status', 'Статус']:
|
||
if col in orders_df.columns:
|
||
order_cols['status'] = col
|
||
break
|
||
|
||
for col in ['notes', 'Примечания', 'note']:
|
||
if col in orders_df.columns:
|
||
order_cols['notes'] = col
|
||
break
|
||
|
||
if 'partner_id' not in order_cols or 'date' not in order_cols:
|
||
print("❌ Не найдены обязательные колонки для заказов")
|
||
return
|
||
|
||
existing_partner_ids = [row[0] for row in conn.execute('SELECT id FROM partners').fetchall()]
|
||
|
||
orders_loaded = 0
|
||
for _, row in orders_df.iterrows():
|
||
try:
|
||
partner_id = int(row[order_cols['partner_id']])
|
||
|
||
if partner_id not in existing_partner_ids:
|
||
print(f" ⚠️ Партнер с ID {partner_id} не найден")
|
||
continue
|
||
|
||
order_date = row[order_cols['date']]
|
||
if isinstance(order_date, pd.Timestamp):
|
||
order_date = order_date.strftime('%Y-%m-%d')
|
||
else:
|
||
order_date = str(order_date)
|
||
|
||
status = str(row.get(order_cols.get('status'), 'новый')) if 'status' in order_cols and pd.notna(
|
||
row.get(order_cols['status'])) else 'новый'
|
||
notes = str(row.get(order_cols.get('notes'), '')) if 'notes' in order_cols and pd.notna(
|
||
row.get(order_cols['notes'])) else ''
|
||
|
||
conn.execute('''
|
||
INSERT INTO orders (partner_id, order_date, status, notes, discount_percent)
|
||
VALUES (?, ?, ?, ?, 0)
|
||
''', (partner_id, order_date, status, notes))
|
||
orders_loaded += 1
|
||
print(f" ✓ Загружен заказ: ID {partner_id}, дата {order_date}")
|
||
|
||
except Exception as e:
|
||
print(f" ⚠️ Ошибка при загрузке заказа: {e}")
|
||
continue
|
||
|
||
print(f" Загружено {orders_loaded} заказов")
|
||
|
||
# 5. Загрузка позиций заказов
|
||
print("5. 📦 Загрузка позиций заказов...")
|
||
items_df = pd.read_excel(order_items_file)
|
||
|
||
print(" Доступные колонки в файле позиций:", list(items_df.columns))
|
||
|
||
item_cols = {}
|
||
|
||
for col in ['order_id', 'Номер заказа', 'order', 'заказ']:
|
||
if col in items_df.columns:
|
||
item_cols['order_id'] = col
|
||
break
|
||
|
||
for col in ['product_id', 'ID товара', 'product', 'товар']:
|
||
if col in items_df.columns:
|
||
item_cols['product_id'] = col
|
||
break
|
||
|
||
for col in ['quantity', 'Количество', 'qty', 'кол']:
|
||
if col in items_df.columns:
|
||
item_cols['quantity'] = col
|
||
break
|
||
|
||
for col in ['price', 'Цена', 'price_at_order']:
|
||
if col in items_df.columns:
|
||
item_cols['price'] = col
|
||
break
|
||
|
||
missing_cols = []
|
||
if 'order_id' not in item_cols:
|
||
missing_cols.append('order_id')
|
||
if 'product_id' not in item_cols:
|
||
missing_cols.append('product_id')
|
||
if 'quantity' not in item_cols:
|
||
missing_cols.append('quantity')
|
||
if 'price' not in item_cols:
|
||
missing_cols.append('price')
|
||
|
||
if missing_cols:
|
||
print(f"❌ Не найдены обязательные колонки: {', '.join(missing_cols)}")
|
||
return
|
||
|
||
existing_order_ids = [row[0] for row in conn.execute('SELECT id FROM orders').fetchall()]
|
||
existing_product_ids = [row[0] for row in conn.execute('SELECT id FROM products').fetchall()]
|
||
|
||
items_loaded = 0
|
||
for index, row in items_df.iterrows():
|
||
try:
|
||
order_id = int(row[item_cols['order_id']])
|
||
product_id = int(row[item_cols['product_id']])
|
||
quantity = int(row[item_cols['quantity']])
|
||
price = float(row[item_cols['price']])
|
||
|
||
if quantity <= 0:
|
||
print(f" ⚠️ Некорректное количество для заказа {order_id}: {quantity}")
|
||
continue
|
||
if price <= 0:
|
||
print(f" ⚠️ Некорректная цена для заказа {order_id}: {price}")
|
||
continue
|
||
|
||
if order_id not in existing_order_ids:
|
||
print(f" ⚠️ Заказ не найден: {order_id}")
|
||
continue
|
||
|
||
if product_id not in existing_product_ids:
|
||
print(f" ⚠️ Товар с ID {product_id} не найден")
|
||
continue
|
||
|
||
conn.execute('''
|
||
INSERT INTO order_items (order_id, product_id, quantity, price_at_order)
|
||
VALUES (?, ?, ?, ?)
|
||
''', (order_id, product_id, quantity, price))
|
||
items_loaded += 1
|
||
print(f" ✓ Загружена позиция: заказ {order_id}, товар {product_id}")
|
||
|
||
except Exception as e:
|
||
print(f" ⚠️ Ошибка при загрузке позиции в строке {index + 2}: {e}")
|
||
continue
|
||
|
||
print(f" Загружено {items_loaded} позиций заказов")
|
||
|
||
print(f"\n✅ Данные успешно загружены!")
|
||
print(f" Типов товаров: {type_count}")
|
||
print(f" Партнеров: {partner_count}")
|
||
print(f" Товаров: {products_loaded}")
|
||
print(f" Заказов: {orders_loaded}")
|
||
print(f" Позиций: {items_loaded}")
|
||
|
||
except Exception as e:
|
||
print(f"❌ Ошибка при загрузке данных: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
import_data_from_files() |