Initial commit

This commit is contained in:
2025-10-18 00:52:08 +03:00
commit e049a302d3
18 changed files with 1541 additions and 0 deletions

78
lib/base_migrator.py Normal file
View File

@@ -0,0 +1,78 @@
import json
import os
from typing import Dict, Any
from abc import abstractmethod
class BaseMigrator:
"""Базовый класс для миграторов с общими методами работы с файлами маппинга."""
def _load_mapping(self, filename: str) -> Dict[int, int]:
"""Загружает маппинг из JSON файла."""
if os.path.exists(filename):
with open(filename, "r", encoding="utf-8") as f:
data = json.load(f)
return {int(k): int(v) for k, v in data.items()}
return {}
def _load_nested_mapping(self, filename: str) -> Dict[Any, Any]:
"""Загрузка вложенного маппинга из JSON-файла (для колонок)."""
if os.path.exists(filename):
with open(filename, 'r') as f:
data = json.load(f)
# Для вложенного маппинга колонок: {project_id: {src_col_id: target_col_id}}
result = {}
for project_id_str, column_map in data.items():
project_id = int(project_id_str)
result[project_id] = {}
for src_col_str, target_col_id in column_map.items():
result[project_id][int(src_col_str)] = int(target_col_id)
return result
return {}
def _save_mapping(self, filename: str, mapping: Dict[int, int]):
"""Сохраняет маппинг в JSON файл."""
with open(filename, "w", encoding="utf-8") as f:
json.dump(mapping, f, ensure_ascii=False, indent=2)
def _save_nested_mapping(self, filename: str, mapping: Dict[Any, Any]):
"""Сохранение вложенного маппинга в JSON-файл."""
# Преобразуем в формат, который можно сериализовать в JSON
serializable_mapping = {}
for project_id, column_map in mapping.items():
serializable_mapping[str(project_id)] = {str(k): v for k, v in column_map.items()}
with open(filename, 'w') as f:
json.dump(serializable_mapping, f, indent=2)
def _delete_mapping_file(self, filename: str) -> bool:
"""
Удаляет файл маппинга, если он существует.
Args:
filename: Путь к файлу маппинга.
Returns:
bool: True, если файл удален или не существует, False в случае ошибки.
"""
try:
if filename and os.path.exists(filename):
os.remove(filename)
print(f"Файл маппинга {filename} удалён")
return True
else:
print("Файл маппинга не найден или не задан")
return True
except Exception as e:
print(f"[{type(e).__name__}] Ошибка при удалении файла маппинга: {e}")
return False
@abstractmethod
def migrate(self):
"""Абстрактный метод для миграции данных."""
pass
@abstractmethod
def delete_all(self):
"""Абстрактный метод для удаления всех данных."""
pass