diff --git a/scripts/migrate_blacklist_to_history.py b/scripts/migrate_blacklist_to_history.py new file mode 100644 index 0000000..cc302ba --- /dev/null +++ b/scripts/migrate_blacklist_to_history.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +""" +Скрипт миграции для переноса записей из blacklist в blacklist_history. +Переносит все существующие записи из таблицы blacklist в таблицу blacklist_history. +""" +import argparse +import asyncio +import os +import sys +from pathlib import Path +from datetime import datetime + +project_root = Path(__file__).resolve().parent.parent +sys.path.insert(0, str(project_root)) + +import aiosqlite + +from logs.custom_logger import logger + +DEFAULT_DB_PATH = "database/tg-bot-database.db" + + +async def main(db_path: str) -> None: + db_path = os.path.abspath(db_path) + if not os.path.exists(db_path): + logger.error("База данных не найдена: %s", db_path) + print(f"Ошибка: база данных не найдена: {db_path}") + return + + async with aiosqlite.connect(db_path) as conn: + await conn.execute("PRAGMA foreign_keys = ON") + + # Проверяем наличие таблицы blacklist_history + cursor = await conn.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name='blacklist_history'" + ) + rows = await cursor.fetchall() + await cursor.close() + + if not rows: + logger.error("Таблица blacklist_history не найдена. Сначала запустите create_blacklist_history_table.py") + print("Ошибка: таблица blacklist_history не найдена. Сначала запустите create_blacklist_history_table.py") + return + + # Получаем все записи из blacklist + cursor = await conn.execute( + "SELECT user_id, message_for_user, date_to_unban, created_at, ban_author FROM blacklist" + ) + blacklist_records = await cursor.fetchall() + await cursor.close() + + if not blacklist_records: + print("В таблице blacklist нет записей для переноса.") + logger.info("В таблице blacklist нет записей для переноса") + return + + logger.info("Найдено записей в blacklist для переноса: %d", len(blacklist_records)) + print(f"Найдено записей в blacklist для переноса: {len(blacklist_records)}") + + # Получаем текущее время в Unix timestamp + current_time = int(datetime.now().timestamp()) + + # Переносим записи в blacklist_history + migrated_count = 0 + skipped_count = 0 + + for record in blacklist_records: + user_id, message_for_user, date_to_unban, created_at, ban_author = record + + # Проверяем, нет ли уже записи для этого user_id с таким же date_ban + # (чтобы избежать дубликатов при повторном запуске) + date_ban = created_at if created_at is not None else current_time + + check_cursor = await conn.execute( + "SELECT id FROM blacklist_history WHERE user_id = ? AND date_ban = ?", + (user_id, date_ban) + ) + existing = await check_cursor.fetchone() + await check_cursor.close() + + if existing: + logger.debug("Запись для user_id=%d с date_ban=%d уже существует, пропускаем", user_id, date_ban) + skipped_count += 1 + continue + + # Вставляем запись в blacklist_history + await conn.execute( + """ + INSERT INTO blacklist_history + (user_id, message_for_user, date_ban, date_unban, ban_author, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?) + """, + ( + user_id, + message_for_user, + date_ban, + date_to_unban, + ban_author, + created_at if created_at is not None else current_time, + current_time + ) + ) + migrated_count += 1 + + await conn.commit() + + logger.info( + "Миграция завершена. Перенесено записей: %d, пропущено (дубликаты): %d", + migrated_count, + skipped_count + ) + print(f"Миграция завершена. Перенесено записей: {migrated_count}, пропущено (дубликаты): {skipped_count}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Перенос записей из blacklist в blacklist_history" + ) + parser.add_argument( + "--db", + default=os.environ.get("DB_PATH", DEFAULT_DB_PATH), + help="Путь к БД (или DB_PATH)", + ) + args = parser.parse_args() + asyncio.run(main(args.db))