github BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot v2.0.8

latest releases: v3.17.0, v3.16.3, v3.16.2...
6 months ago

Миграция базы данных - Исправление дублирующихся подписок

v2.0.7...v2.0.8

Проблема

В боте была обнаружена ошибка, при которой после истечения подписки создавалась новая запись вместо обновления существующей. Это приводило к дублированию записей в таблице subscriptions.

Решение

Добавлена автоматическая миграция, которая:

  1. Обнаруживает дублирующиеся подписки (несколько записей для одного user_id)
  2. Удаляет старые записи, оставляя только самую новую
  3. Работает с разными типами баз данных (SQLite, PostgreSQL, MySQL)

Запуск

Автоматический запуск

Миграция запускается автоматически при старте бота:

# С Docker
docker-compose up

# Без Docker
python main.py

Ручная проверка состояния БД

# Создайте скрипт check_subscriptions.py
python -c "
import asyncio
from app.database.universal_migration import run_universal_migration
asyncio.run(run_universal_migration())
"

Переменные окружения

  • SKIP_MIGRATION=true - пропустить миграцию при запуске (не рекомендуется)
  • DATABASE_URL - строка подключения к базе данных

Поддерживаемые базы данных

  • SQLite (по умолчанию): sqlite+aiosqlite:///./bot.db
  • PostgreSQL: postgresql+asyncpg://user:password@host:port/dbname
  • MySQL: mysql+aiomysql://user:password@host:port/dbname

Логи миграции

Миграция выводит подробные логи:

INFO - Тип базы данных: sqlite
INFO - Всего подписок: 150
INFO - Уникальных пользователей: 140
INFO - Найдено 10 пользователей с дублирующимися подписками
INFO - Удалено 15 дублирующихся подписок для пользователя 123
INFO - Всего удалено дублирующихся подписок: 15
INFO - === МИГРАЦИЯ ЗАВЕРШЕНА УСПЕШНО ===

Безопасность

  • Миграция создает резервную копию логики - удаляет только дубликаты, оставляя самую новую запись
  • Если миграция не может определить самую новую запись, она оставляет запись с максимальным id
  • Миграция выполняется в транзакции - при ошибке все изменения откатываются

Проблемы и решения

База данных заблокирована

# Остановите все процессы, использующие БД
docker-compose down
# Запустите снова
docker-compose up

Ошибка "UNIQUE constraint failed"

Это означает, что миграция не была выполнена до добавления unique=True в модель. Выполните миграцию вручную.

Принудительная очистка (ОСТОРОЖНО!)

-- Только для крайних случаев! Создайте бэкап!
DELETE FROM subscriptions 
WHERE id NOT IN (
    SELECT MIN(id) 
    FROM subscriptions 
    GROUP BY user_id
);

Разработка

После успешной миграции можно безопасно обновлять модели:

# В models.py можно добавить:
user_id = Column(Integer, ForeignKey("users.id"), nullable=False, unique=True)

Тестирование

Для тестирования на новой базе установите переменную:

export SKIP_MIGRATION=true

Тогда миграция не запустится автоматически.

Don't miss a new remnawave-bedolaga-telegram-bot release

NewReleases is sending notifications on new releases.