перед внедрением веб интерфейса и API для взаимодействием с gemini.
This commit is contained in:
+80
-25
@@ -35,23 +35,22 @@ def print_stats():
|
||||
|
||||
|
||||
def print_snapshots_list(date_str=None):
|
||||
"""Выводит реестр снапшотов с идеальным вертикальным выравниванием дефисов и цифр."""
|
||||
"""Выводит реестр снапшотов с отображением даты и точного времени среза."""
|
||||
rows = get_available_snapshots(date_str)
|
||||
|
||||
print("\n" + "=" * 95)
|
||||
print("\n" + "=" * 105)
|
||||
print(f"📸 РЕЕСТР СОХРАНЕННЫХ СНАПШОТОВ (СВЕРХУ СВЕЖИЕ) {'ЗА ЛОГИ ' + date_str if date_str else ''}:")
|
||||
print("=" * 95)
|
||||
print("=" * 105)
|
||||
|
||||
header = f"{'ID снапшота':<16} | {'Дата снапшота (создания)':<24} | {'Дата среза':<12} | {'Записей':<8}"
|
||||
header = f"{'ID снапшота':<16} | {'Дата снапшота (создания)':<24} | {'Дата и время среза':<20} | {'Записей':<8}"
|
||||
print(header)
|
||||
print("-" * 95)
|
||||
print("-" * 105)
|
||||
|
||||
if not rows:
|
||||
print("Снапшотов пока нет.")
|
||||
print("=" * 95 + "\n")
|
||||
print("=" * 105 + "\n")
|
||||
return
|
||||
|
||||
# Внутрипитоновская хронологическая сортировка: сначала snap_time DESC, затем seq_num DESC
|
||||
def snapshot_sort_key(row):
|
||||
snap_id = row[0] or ""
|
||||
snap_time = row[2] or ""
|
||||
@@ -72,15 +71,43 @@ def print_snapshots_list(date_str=None):
|
||||
snap_time = r[2] if r[2] else '—'
|
||||
count = r[3]
|
||||
|
||||
# 💡 ИДЕАЛЬНОЕ ВЫРАВНИВАНИЕ: если нет префикса Y, добавляем ведущий пробел
|
||||
# Извлекаем время (ЧЧ:ММ:СС) из snapshot_time, если оно есть
|
||||
time_part = "—"
|
||||
if snap_time and " " in snap_time:
|
||||
time_part = snap_time.split(" ")[1]
|
||||
|
||||
slice_datetime_str = f"{log_date} {time_part}" if time_part != "—" else log_date
|
||||
|
||||
if not snap_id.startswith("Y"):
|
||||
formatted_snap_id = f" {snap_id}"
|
||||
else:
|
||||
formatted_snap_id = snap_id
|
||||
|
||||
print(f"{formatted_snap_id:<16} | {snap_time:<24} | {log_date:<12} | {count:<8}")
|
||||
print(f"{formatted_snap_id:<16} | {snap_time:<24} | {slice_datetime_str:<20} | {count:<8}")
|
||||
|
||||
print("=" * 95 + "\n")
|
||||
print("=" * 105 + "\n")
|
||||
|
||||
|
||||
def delete_snapshot_by_id(snapshot_id: str):
|
||||
"""Удаляет конкретный снапшот из таблицы scud_logs по его ID."""
|
||||
with get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM scud_logs WHERE snapshot_id = ?", (snapshot_id,))
|
||||
deleted_count = cursor.rowcount
|
||||
conn.commit()
|
||||
print(f"\n[✓] Успешно удален снапшот [{snapshot_id}]. Удалено строк: {deleted_count}\n")
|
||||
return deleted_count
|
||||
|
||||
|
||||
def delete_snapshots_by_date(date_str: str):
|
||||
"""Удаляет все снапшоты за указанную дату (например, '04.08.2026')."""
|
||||
with get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM scud_logs WHERE log_date = ? OR snapshot_id LIKE ?", (date_str, f"%{date_str.replace('.', '')}%"))
|
||||
deleted_count = cursor.rowcount
|
||||
conn.commit()
|
||||
print(f"\n[✓] Успешно удалены все снапшоты за дату [{date_str}]. Удалено строк: {deleted_count}\n")
|
||||
return deleted_count
|
||||
|
||||
|
||||
def inspect_scud(snapshot_id=None, date_str=None, export_xlsx=None):
|
||||
@@ -171,28 +198,42 @@ def main():
|
||||
help_text = """
|
||||
CLI-утилита инспекции и управления SQLite базой данных СКУД (scud_orion_ai.db)
|
||||
|
||||
ДОСТУПНЫЕ КОМАНДЫ:
|
||||
stats -- Общая статистика строк по всем таблицам БД
|
||||
snapshots [ДД.ММ.ГГГГ] -- Посмотреть список всех снапшотов (опционально за дату)
|
||||
scud [--snapshot ID] [--export-xlsx NAME] -- Инспекция логов СКУД и опциональный экспорт в Excel
|
||||
anomalies -- Посмотреть все найденные аномалии СКУД ⟷ 1С
|
||||
rules -- Посмотреть правила Базы Знаний ИИ из SQLite
|
||||
dump [output.xlsx] -- Полный дамп всех таблиц БД в многостраничный Excel
|
||||
snapshot del [ID] или [--day ДД.ММ.ГГГГ] -- Удаление снапшотов по ID или за весь день
|
||||
|
||||
ПРИМЕРЫ ЗАПУСКА:
|
||||
python scripts/db_cli.py scud -- Выгрузка СКУД за текущую дату (последний снапшот)
|
||||
python scripts/db_cli.py scud --snapshot 20260805-001 -- Выгрузка СКУД строго по ID конкретного снапшота
|
||||
python scripts/db_cli.py scud --export-xlsx debug_today -- Выгрузить срез СКУД в форматированный Excel-файл
|
||||
python scripts/db_cli.py snapshots -- Посмотреть список всех снапшотов с их ID (от новых к старым)
|
||||
python scripts/db_cli.py snapshots 04.08.2026 -- Посмотреть снапшоты за конкретную дату
|
||||
python scripts/db_cli.py stats -- Общая статистика строк по всем таблицам БД
|
||||
python scripts/db_cli.py anomalies -- Посмотреть все найденные аномалии СКУД ⟷ 1С
|
||||
python scripts/db_cli.py rules -- Посмотреть правила Базы Знаний ИИ из SQLite
|
||||
python scripts/db_cli.py dump [output.xlsx] -- Полный дамп всех таблиц БД в многостраничный Excel
|
||||
python scripts/db_cli.py stats
|
||||
python scripts/db_cli.py snapshots 04.08.2026
|
||||
python scripts/db_cli.py scud --snapshot Y20260805-007 --export-xlsx вчера_1
|
||||
python scripts/db_cli.py snapshot del Y20260805-007
|
||||
python scripts/db_cli.py snapshot del --day 04.08.2026
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description=help_text,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
add_help=True
|
||||
)
|
||||
parser.add_argument('command', nargs='?', default='stats', choices=['stats', 'snapshots', 'scud', 'anomalies', 'rules', 'dump'], help="Команда: stats | snapshots | scud | anomalies | rules | dump")
|
||||
parser.add_argument('param', nargs='?', default=None, help="Параметр команды (дата в формате ДД.ММ.ГГГГ или имя файла)")
|
||||
parser.add_argument('--snapshot', type=str, default=None, help="Выбрать конкретный ID снапшота для инспекции (например, '20260805-001', 'Y20260805-001')")
|
||||
parser.add_argument('--export-xlsx', type=str, default=None, help="Экспортировать выбранный срез СКУД в Excel-файл")
|
||||
parser.add_argument('command', nargs='?', default=None, choices=['stats', 'snapshots', 'scud', 'anomalies', 'rules', 'dump', 'snapshot'], help="Основная команда")
|
||||
parser.add_argument('action', nargs='?', default=None, help="Дополнительное действие (например, 'del')")
|
||||
parser.add_argument('param', nargs='?', default=None, help="Параметр (дата, ID снапшота или имя файла)")
|
||||
parser.add_argument('--snapshot', type=str, default=None, help="ID конкретного снапшота для инспекции")
|
||||
parser.add_argument('--export-xlsx', type=str, default=None, help="Экспорт среза СКУД в Excel-файл")
|
||||
parser.add_argument('--day', type=str, default=None, help="Удалить снапшоты за конкретный день (ДД.ММ.ГГГГ)")
|
||||
|
||||
# Если аргументы вообще не переданы, выводим статистику по умолчанию (или справку)
|
||||
if len(sys.argv) == 1:
|
||||
print_stats()
|
||||
return
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Валидация команд
|
||||
if args.command == 'stats':
|
||||
print_stats()
|
||||
elif args.command == 'snapshots':
|
||||
@@ -206,7 +247,21 @@ CLI-утилита инспекции и управления SQLite базой
|
||||
elif args.command == 'dump':
|
||||
filename = args.param if args.param else "db_dump_full.xlsx"
|
||||
dump_all_to_excel(filename)
|
||||
|
||||
elif args.command == 'snapshot':
|
||||
if args.action == 'del':
|
||||
if args.day:
|
||||
delete_snapshots_by_date(args.day)
|
||||
elif args.param:
|
||||
delete_snapshot_by_id(args.param)
|
||||
else:
|
||||
print("\n[❌] Ошибка: Не указан ID снапшота или параметр --day для удаления.")
|
||||
print("Пример: python scripts/db_cli.py snapshot del Y20260805-007\n")
|
||||
else:
|
||||
print(f"\n[❌] Ошибка: Неизвестное действие '{args.action}' для команды snapshot.")
|
||||
print("Используйте: python scripts/db_cli.py snapshot del [ID или --day 'ДД.ММ.ГГГГ']\n")
|
||||
else:
|
||||
print(f"\n[❌] Ошибка: Неизвестная команда.")
|
||||
parser.print_help()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user