Update backup_service.py

This commit is contained in:
Egor
2026-01-13 01:31:02 +03:00
committed by GitHub
parent e5faaa6c6f
commit 31241a6f01
+36 -3
View File
@@ -819,7 +819,7 @@ class BackupService:
try:
if clear_existing:
logger.warning("🗑️ Очищаем существующие данные...")
await self._clear_database_tables(db)
await self._clear_database_tables(db, backup_data)
models_for_restore = self._get_models_for_backup(True)
models_by_table = {
@@ -888,6 +888,9 @@ class BackupService:
restored_tables += 1
logger.info("✅ Таблица %s восстановлена", table_name)
# Flush все изменения перед обновлением реферальных связей
await db.flush()
await self._update_user_referrals(db, backup_data)
assoc_tables, assoc_records = await self._restore_association_tables(
@@ -1201,10 +1204,29 @@ class BackupService:
) -> int:
restored_count = 0
# Кешируем существующие tariff_id для проверки FK
existing_tariff_ids = set()
if table_name == "subscriptions":
try:
result = await db.execute(select(Tariff.id))
existing_tariff_ids = {row[0] for row in result.fetchall()}
logger.info(f"📋 Найдено {len(existing_tariff_ids)} существующих тарифов для валидации FK")
except Exception as e:
logger.warning(f"⚠️ Не удалось получить список тарифов: {e}")
for record_data in records:
try:
processed_data = self._process_record_data(record_data, model, table_name)
# Валидация FK для subscriptions.tariff_id
if table_name == "subscriptions" and "tariff_id" in processed_data:
tariff_id = processed_data.get("tariff_id")
if tariff_id is not None and tariff_id not in existing_tariff_ids:
logger.warning(
f"⚠️ Тариф {tariff_id} не найден, устанавливаем tariff_id=NULL для подписки"
)
processed_data["tariff_id"] = None
primary_key_col = self._get_primary_key_column(model)
if primary_key_col and primary_key_col in processed_data:
@@ -1236,7 +1258,7 @@ class BackupService:
return restored_count
async def _clear_database_tables(self, db: AsyncSession):
async def _clear_database_tables(self, db: AsyncSession, backup_data: Optional[Dict[str, Any]] = None):
tables_order = [
"server_squad_promo_groups",
"ticket_messages", "tickets", "support_audit_logs",
@@ -1248,11 +1270,22 @@ class BackupService:
"mulenpay_payments", "pal24_payments",
"transactions", "welcome_texts", "subscriptions",
"promocodes", "users", "promo_groups",
"tariffs", # tariffs должен очищаться ПОСЛЕ subscriptions (FK зависимость)
"server_squads", "squads", "service_rules",
"system_settings", "web_api_tokens", "monitoring_logs"
]
# Таблицы, которые не нужно очищать если в бекапе нет данных для них
# (чтобы сохранить существующие настройки)
preserve_if_no_backup = {"tariffs", "promo_groups", "server_squads", "squads"}
for table_name in tables_order:
# Проверяем, нужно ли сохранить таблицу
if backup_data and table_name in preserve_if_no_backup:
if not backup_data.get(table_name):
logger.info(f"⏭️ Пропускаем очистку {table_name} (нет данных в бекапе)")
continue
try:
await db.execute(text(f"DELETE FROM {table_name}"))
logger.info(f"🗑️ Очищена таблица {table_name}")