# Data Replication Service Сервис репликации данных из множественных источников (MSSQL, PostgreSQL) в целевую PostgreSQL базу с использованием DLT (Data Load Tool), FastAPI и планировщика задач APScheduler. ## Особенности - ✅ **Динамическое управление источниками данных** - Добавляйте и удаляйте источники через REST API без перезагрузки сервиса - ✅ Поддержка множественных типов источников (MSSQL, PostgreSQL) - ✅ Репликация таблиц с использованием DLT для оптимальной производительности - ✅ Обработка логов изменений (Life таблицы с INSERT, UPDATE, DELETE операциями) - ✅ Индивидуальное расписание для каждой таблицы (Cron выражения) - ✅ Управление конфликтами времени выполнения (очередь задач) - ✅ REST API для полного управления процессом репликации - ✅ Кеширование подключений для оптимизации производительности - ✅ Логирование и мониторинг задач репликации - ✅ Health check и статистика ## Архитектурные улучшения ### Переход на DataSource-based конфигурацию **Раньше (static конфигурация):** - Источники данных определялись в `.env` файле - Требовалась перезагрузка сервиса для изменения конфигурации - Одна MSSQL и одна PostgreSQL база фиксированно **Теперь (динамическая конфигурация):** - Источники хранятся в БД (таблица `data_sources`) - Полное управление через REST API - Поддержка множественных источников каждого типа - Без необходимости перезагрузки сервиса - Кеширование подключений с TTL = 5 минут ## Структура проекта ``` replication_service/ ├── main.py # Главное приложение FastAPI ├── config.py # Конфигурация и переменные окружения ├── models.py # ORM модели (SQLAlchemy) - включая DataSource ├── database.py # Управление подключениями с кешированием ├── api.py # REST API endpoints (DataSource + Migration) ├── replication.py # Логика репликации данных ├── scheduler.py # Планировщик задач с управлением конфликтами ├── migrate_to_data_sources.py # Скрипт миграции из старой конфигурации ├── examples_api.py # Примеры использования новой API ├── requirements.txt # Зависимости Python ├── DATA_SOURCES.md # Документация по управлению источниками ├── .env.example # Пример файла переменных окружения └── README.md # Документация ``` ## Установка ### 1. Создать виртуальное окружение ```bash python -m venv venv source venv/bin/activate # Linux/Mac # или venv\Scripts\activate # Windows ``` ### 2. Установить зависимости ```bash pip install -r requirements.txt ``` ### 3. Настроить переменные окружения Скопировать `.env.example` в `.env` и заполнить данные целевой базы данных PostgreSQL: ```bash cp .env.example .env ``` ```env # PostgreSQL Connection (целевая база для всех репликаций) POSTGRES_HOST=your_postgres_host POSTGRES_DATABASE=replication_db POSTGRES_USERNAME=postgres POSTGRES_PASSWORD=your_password POSTGRES_PORT=5432 ``` **Важно:** Источники данных больше НЕ конфигурируются через `.env` файл! ### 4. Инициализировать базу данных ```bash python -c "from database import DatabaseManager; DatabaseManager.init_postgres_db()" ``` ## Запуск ```bash python main.py ``` или ```bash uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` Сервис будет доступен по адресу: `http://localhost:8000` ## Быстрый старт с новой API ### 1. Создать источник данных ```bash curl -X POST http://localhost:8000/api/v1/data-sources \ -H "Content-Type: application/json" \ -d '{ "name": "MSSQL Production", "source_type": "mssql", "host": "mssql-server.example.com", "port": 1433, "database": "MyDatabase", "username": "sa", "password": "Password123!" }' ``` **Ответ:** ```json { "id": 1, "name": "MSSQL Production", "source_type": "mssql", "host": "mssql-server.example.com", "port": 1433, "database": "MyDatabase", "default_schema": "dbo", "is_active": true, "created_at": "2024-01-15T10:30:00", "updated_at": "2024-01-15T10:30:00" } ``` ### 2. Проверить подключение ```bash curl -X POST http://localhost:8000/api/v1/data-sources/1/test ``` **Ответ:** ```json { "source_id": 1, "connection_ok": true } ``` ### 3. Создать расписание репликации ```bash curl -X POST http://localhost:8000/api/v1/migration-tables \ -H "Content-Type: application/json" \ -d '{ "table_name": "Orders", "source_id": 1, "cron_schedule": "0 2 * * *", "source_schema": "dbo", "target_schema": "public" }' ``` **Ответ:** ```json { "id": 1, "table_name": "Orders", "source_id": 1, "source_schema": "dbo", "target_schema": "public", "cron_schedule": "0 2 * * *", "is_active": true, "created_at": "2024-01-15T10:35:00", "updated_at": "2024-01-15T10:35:00" } ``` ### 4. Запустить примеры API ```bash python examples_api.py ``` Этот скрипт демонстрирует все основные операции с API. ## API Endpoints ### Health Check - `GET /api/v1/health` - Проверка здоровья сервиса **Ответ:** "status": "healthy", "mssql_connected": true, "postgres_connected": true, "timestamp": "2026-03-29T10:00:00" } ``` ### Управление таблицами миграции #### Создать таблицу для миграции ```bash POST /api/v1/migration-tables Content-Type: application/json { "table_name": "Orders", "cron_schedule": "0 2 * * *", # Каждый день в 2:00 "source_schema": "dbo", "target_schema": "public" } ``` #### Получить список всех таблиц ```bash GET /api/v1/migration-tables ``` #### Получить информацию о конкретной таблице ```bash GET /api/v1/migration-tables/{table_id} ``` #### Удалить таблицу из миграции ```bash DELETE /api/v1/migration-tables/{table_id} ``` ### Управление планировщиком #### Получить статус планировщика ```bash GET /api/v1/scheduler/status ``` **Ответ:** ```json { "is_running": true, "migration_tables_count": 5, "running_jobs": { "1": 1680000000.123 }, "queued_jobs": [] } ``` #### Запустить планировщик ```bash POST /api/v1/scheduler/start ``` #### Остановить планировщик ```bash POST /api/v1/scheduler/stop ``` #### Получить список задач планировщика ```bash GET /api/v1/scheduler/jobs ``` ### История и статистика #### Получить список задач репликации ```bash GET /api/v1/replication-jobs?limit=100&offset=0&status=success ``` #### Получить информацию о конкретной задаче ```bash GET /api/v1/replication-jobs/{job_id} ``` #### Получить статистику ```bash GET /api/v1/statistics ``` **Ответ:** ```json { "total_jobs": 150, "successful_jobs": 148, "failed_jobs": 2, "success_rate": 98.67, "timestamp": "2026-03-29T10:00:00" } ``` ## Примеры использования ### 1. Добавить таблицу для репликации с расписанием ```bash curl -X POST "http://localhost:8000/api/v1/migration-tables" \ -H "Content-Type: application/json" \ -d '{ "table_name": "Customers", "cron_schedule": "*/30 * * * *", "source_schema": "dbo", "target_schema": "public" }' ``` Это расписание означает: "выполнять репликацию каждые 30 минут" ### 2. Добавить несколько таблиц с разным расписанием ```bash # Orders - каждый день в 2:00 AM curl -X POST "http://localhost:8000/api/v1/migration-tables" \ -H "Content-Type: application/json" \ -d '{"table_name": "Orders", "cron_schedule": "0 2 * * *"}' # Products - каждый день в 3:00 AM curl -X POST "http://localhost:8000/api/v1/migration-tables" \ -H "Content-Type: application/json" \ -d '{"table_name": "Products", "cron_schedule": "0 3 * * *"}' ``` ### 3. Контролировать расписание при конфликтах Если две таблицы имеют пересекающееся расписание, они будут автоматически добавлены в очередь и выполняться последовательно: ```bash # Таблица 1: каждый день в 2:00 AM # Таблица 2: каждый день в 2:15 AM # Таблица 3: каждый день в 2:30 AM # Все три задачи начнут выполняться в порядке очереди ``` ## Спецификация Cron для расписания **Формат:** `<минуты> <часы> <день месяца> <месяц> <день недели>` **Примеры:** - `0 2 * * *` - Каждый день в 2:00 AM - `*/30 * * * *` - Каждые 30 минут - `0 0 * * 0` - Каждое воскресенье в полночь - `0 9,12,15 * * *` - В 9:00, 12:00 и 15:00 каждый день - `0 */4 * * *` - Каждые 4 часа - `0 0 1 * *` - Первый день каждого месяца в полночь ## Life таблицы **Life таблицы** - это таблицы в MSSQL, которые хранят логи транзакций для оригинальных таблиц. **Соглашение по именованию:** - Оригинальная таблица: `Orders` - Life таблица: `LifeOrders` Сервис автоматически обрабатывает следующие операции: - **INSERT** - Добавление новых записей - **UPDATE** - Обновление существующих записей - **DELETE** - Удаление записей ## Мониторинг и отладка ### Логи приложения Логи выводятся с информацией о каждом этапе репликации: ``` 2026-03-29 10:00:00 - scheduler - INFO - Starting replication for table Orders 2026-03-29 10:00:15 - replication - INFO - Successfully replicated 1250 rows from Orders 2026-03-29 10:00:25 - scheduler - INFO - Processing queued job for Products ``` ### API Documentation После запуска приложения, интерактивная документация доступна по адресам: - Swagger UI: `http://localhost:8000/docs` - ReDoc: `http://localhost:8000/redoc` ## Конфигурация ### DatabaseManager ```python from database import DatabaseManager # Проверить подключение к MSSQL DatabaseManager.test_mssql_connection() # Проверить подключение к PostgreSQL DatabaseManager.test_postgres_connection() # Инициализировать таблицы PostgreSQL DatabaseManager.init_postgres_db() ``` ### SchedulerManager ```python from scheduler import scheduler_manager # Добавить таблицу scheduler_manager.add_migration_table( table_name="Orders", cron_schedule="0 2 * * *" ) # Получить список таблиц tables = scheduler_manager.get_migration_tables() # Получить текущие выполняющиеся задачи running = scheduler_manager.get_running_jobs() # Получить задачи в очереди queued = scheduler_manager.get_queued_jobs() ``` ## Производительность - **Асинхронная обработка**: Использует APScheduler для фонового выполнения - **Очередь задач**: Автоматическое управление конфликтами расписания - **Оптимизация DLT**:批量 обработка данных для минимизации операций с БД - **Connection pooling**: Эффективное использование подключений к БД ## Безопасность - Используйте переменные окружения для конфиденциальных данных (не коммитьте `.env`) - Настройте `.env.example` как шаблон для других разработчиков - Рассмотрите использование API ключей для защиты endpoints - Логируйте все операции репликации для аудита ## Развертывание на производстве ### Docker ```dockerfile FROM python:3.11 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] ``` ### Docker Compose ```yaml version: '3.8' services: replication-service: build: . ports: - "8000:8000" environment: MSSQL_SERVER: mssql POSTGRES_HOST: postgres depends_on: - postgres postgres: image: postgres:15 environment: POSTGRES_PASSWORD: postgres ``` ## Решение проблем ### Ошибка подключения к MSSQL 1. Проверить, запущен ли сервер MSSQL 2. Проверить правильность USER/PASSWORD в `.env` 3. Убедиться, что брандмауэр не блокирует порт 1433 4. Проверить права доступа sa пользователя ### Ошибка подключения к PostgreSQL 1. Проверить, запущен ли сервер PostgreSQL 2. Проверить правильность HOST/PORT в `.env` 3. Убедиться, что база данных с заданным именем существует 4. Проверить права доступа пользователя ### DLT ошибки 1. Убедиться, что таблица существует в MSSQL 2. Проверить права доступа на чтение таблицы 3. Проверить, что целевая схема существует в PostgreSQL ## Лицензия MIT ## Поддержка Для сообщений об ошибках и предложений создавайте Issues в репозитории.