Files
scud_ai/main_etl.py
T

94 lines
4.5 KiB
Python

"""
===============================================================================
FILE: main_etl.py
PROJECT: SCUD Orion AI (Unified Architecture)
ROLE: Главная CLI-точка входа для запуска ежедневного контроллинга СКУД ⟷ 1С.
AI-CONTEXT-ANCHORS:
- ANCHOR[MAIN_CLI_ENTRY]: Парсинг CLI-флагов и запуск конвейера.
===============================================================================
"""
import sys
import argparse
from datetime import datetime
from core.database import init_db, get_latest_snapshot_time
from services.share_copier import copy_1c_files_from_share
from services.data_validator import check_file_freshness
from services.scud_export import run_export
from services.scud_etl.pipeline import run_controlling_pipeline
# ANCHOR[MAIN_CLI_ENTRY]
def main():
help_text = """
Система автоматизированного контроллинга СКУД ⟷ 1С:ЗУП (scud_orion_ai)
ПРИМЕРЫ ЗАПУСКА:
python main_etl.py -- Обычный дневной запуск
python main_etl.py --skip-export -- Расчет отчета по ПОСЛЕДНЕМУ имеющемуся снапшоту из SQLite
python main_etl.py --snapshot 20260820-001 -- Расчет отчета строго по ID снапшота
python main_etl.py -d -- Запуск в режиме расширенной отладки (DEBUG)
"""
parser = argparse.ArgumentParser(description=help_text, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-d', '--debug', action='store_true', help="Режим отладки (DEBUG)")
parser.add_argument('--skip-export', action='store_true', help="Расчет отчета по последнему снапшоту из SQLite")
parser.add_argument('--snapshot', type=str, default=None, help="ID конкретного снапшота")
args = parser.parse_args()
print("=" * 60)
print(f"ЗАПУСК СИСТЕМЫ МОДУЛЬНОГО КОНТРОЛЛИНГА СКУД ⟷ 1С {'[DEBUG MODE]' if args.debug else ''}")
print("=" * 60)
init_db()
# Определение режима работы и вывод статусов
if args.snapshot:
print(f"[📸] РЕЖИМ СНАПШОТА: Расчет отчета строго по срезу '{args.snapshot}'")
elif args.skip_export:
last_snap = get_latest_snapshot_time()
print(f"[📸] РЕЖИМ --skip-export: Используем последний снапшот из SQLite ('{last_snap}')")
else:
current_snap = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[📸] СФОРМИРОВАН НОВЫЙ СНАПШОТ: '{current_snap}'")
has_today_1c = True
# Прямой экспорт и проверка сетевой шары (если не режим снапшотов)
if not args.skip_export and not args.snapshot:
try:
run_export(save_xlsx=True, debug=args.debug)
except Exception as e:
print(f"[⚠️] Ошибка автоэкспорта из MS SQL: {e}. Переходим к записям SQLite.")
copy_1c_files_from_share()
print("[1/5] Проверка актуальности и свежести входных данных...")
is_valid, warnings, errors, has_today_1c = check_file_freshness()
if warnings:
print("\n--- ⚠️ ПРЕДУПРЕЖДЕНИЯ ОБ АКТУАЛЬНОСТИ ---")
for w in warnings:
print(f" • {w}")
print("-" * 45)
if not is_valid:
print("🛑 ОСТАНОВКА: Отсутствуют критически важные файлы за вчера!")
for e in errors:
print(f" {e}")
sys.exit(1)
print("[✓] Проверка доступности данных успешно пройдена!\n")
else:
print("[0/5] Пропуск прямого экспорта из MS SQL (чтение из базы SQLite)...")
print("[1/5] Пропуск проверки сетевой шары (все данные читаются из SQLite)...")
# Запуск конвейера
run_controlling_pipeline(
snapshot_param=args.snapshot,
skip_export=args.skip_export,
debug=args.debug,
has_today_1c=has_today_1c
)
if __name__ == "__main__":
main()