feature/chat-system #1
56
MIGRATION_006_REPORT.md
Normal file
56
MIGRATION_006_REPORT.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Отчёт о Миграции База Данных 006
|
||||
|
||||
## Дата: 17 ноября 2025 г.
|
||||
|
||||
## Проблема
|
||||
При рефакторинге и применении новой архитектуры выяснилось, что в базе данных отсутствуют некоторые столбцы, которые присутствуют в моделях SQLAlchemy.
|
||||
|
||||
## Отсутствующие столбцы:
|
||||
|
||||
### 1. Таблица `participations`:
|
||||
- **`account_id`** (INTEGER) - внешний ключ на таблицу `accounts`
|
||||
|
||||
### 2. Таблица `winners`:
|
||||
- **`is_notified`** (BOOLEAN) - флаг уведомления победителя
|
||||
- **`is_claimed`** (BOOLEAN) - флаг получения приза
|
||||
- **`claimed_at`** (TIMESTAMP WITH TIME ZONE) - время получения приза
|
||||
|
||||
## Решение
|
||||
Создана миграция **006_fix_missing_columns.py** которая:
|
||||
|
||||
### Добавляет:
|
||||
1. **participations.account_id** с внешним ключом на accounts(id)
|
||||
2. **winners.is_notified** с значением по умолчанию FALSE
|
||||
3. **winners.is_claimed** с значением по умолчанию FALSE
|
||||
4. **winners.claimed_at** без значения по умолчанию (NULL)
|
||||
|
||||
### Особенности реализации:
|
||||
- Использует `DO $$ ... END $$;` блоки для безопасного добавления столбцов
|
||||
- Проверяет существование столбцов перед добавлением (idempotent)
|
||||
- Включает откат (downgrade) функцию для отмены изменений
|
||||
- Поддерживает повторное выполнение без ошибок
|
||||
|
||||
## Применение миграции:
|
||||
```bash
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
## Результат:
|
||||
✅ Все столбцы добавлены успешно
|
||||
✅ Схема БД соответствует моделям SQLAlchemy
|
||||
✅ Бот может создавать записи в таблице winners без ошибок
|
||||
✅ Миграция готова для production развертывания
|
||||
|
||||
## Версия после применения:
|
||||
- **До**: 005 (add_chat_system)
|
||||
- **После**: 006 (fix_missing_columns) ← HEAD
|
||||
|
||||
---
|
||||
|
||||
## Для разработчиков:
|
||||
При развертывании на новых серверах достаточно выполнить:
|
||||
```bash
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
Миграция автоматически проверит и добавит отсутствующие столбцы.
|
||||
25
README.md
25
README.md
@@ -143,19 +143,28 @@ ADMIN_IDS=123456789
|
||||
LOG_LEVEL=INFO
|
||||
```
|
||||
|
||||
### 3. Инициализация миграций базы данных
|
||||
### 3. Инициализация и миграции базы данных
|
||||
|
||||
```bash
|
||||
# Инициализация Alembic
|
||||
alembic init migrations
|
||||
|
||||
# Создание первой миграции
|
||||
alembic revision --autogenerate -m "Initial migration"
|
||||
|
||||
# Применение миграций
|
||||
# Применение всех миграций (рекомендуется)
|
||||
alembic upgrade head
|
||||
|
||||
# Проверка текущей версии
|
||||
alembic current
|
||||
|
||||
# Просмотр истории миграций
|
||||
alembic history
|
||||
```
|
||||
|
||||
**📋 Список миграций:**
|
||||
- **001** - Инициализация таблиц
|
||||
- **003** - Добавление регистрации и счетов
|
||||
- **004** - Добавление claimed_at поля
|
||||
- **005** - Добавление системы чата
|
||||
- **006** - Исправление отсутствующих столбцов ✨
|
||||
|
||||
> **Важно**: При развертывании всегда выполняйте `alembic upgrade head` для применения всех миграций.
|
||||
|
||||
### 4. Запуск бота
|
||||
|
||||
```bash
|
||||
|
||||
90
migrations/versions/006_fix_missing_columns.py
Normal file
90
migrations/versions/006_fix_missing_columns.py
Normal file
@@ -0,0 +1,90 @@
|
||||
"""Add missing columns to fix database schema
|
||||
|
||||
Revision ID: 006
|
||||
Revises: 005
|
||||
Create Date: 2025-11-17 05:35:00.000000
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '006'
|
||||
down_revision = '005'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Добавляем отсутствующий столбец account_id в participations (если еще не существует)
|
||||
op.execute("""
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='participations' AND column_name='account_id') THEN
|
||||
ALTER TABLE participations ADD COLUMN account_id INTEGER;
|
||||
ALTER TABLE participations
|
||||
ADD CONSTRAINT fk_participations_account_id
|
||||
FOREIGN KEY (account_id) REFERENCES accounts(id)
|
||||
ON DELETE SET NULL;
|
||||
END IF;
|
||||
END $$;
|
||||
""")
|
||||
|
||||
# Добавляем отсутствующие столбцы в winners
|
||||
op.execute("""
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='winners' AND column_name='is_notified') THEN
|
||||
ALTER TABLE winners ADD COLUMN is_notified BOOLEAN DEFAULT FALSE;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='winners' AND column_name='is_claimed') THEN
|
||||
ALTER TABLE winners ADD COLUMN is_claimed BOOLEAN DEFAULT FALSE;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='winners' AND column_name='claimed_at') THEN
|
||||
ALTER TABLE winners ADD COLUMN claimed_at TIMESTAMP WITH TIME ZONE;
|
||||
END IF;
|
||||
END $$;
|
||||
""")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# Удаляем добавленные столбцы в обратном порядке
|
||||
|
||||
# Удаляем столбцы из winners
|
||||
op.execute("""
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='winners' AND column_name='claimed_at') THEN
|
||||
ALTER TABLE winners DROP COLUMN claimed_at;
|
||||
END IF;
|
||||
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='winners' AND column_name='is_claimed') THEN
|
||||
ALTER TABLE winners DROP COLUMN is_claimed;
|
||||
END IF;
|
||||
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='winners' AND column_name='is_notified') THEN
|
||||
ALTER TABLE winners DROP COLUMN is_notified;
|
||||
END IF;
|
||||
END $$;
|
||||
""")
|
||||
|
||||
# Удаляем account_id из participations
|
||||
op.execute("""
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='participations' AND column_name='account_id') THEN
|
||||
ALTER TABLE participations DROP CONSTRAINT IF EXISTS fk_participations_account_id;
|
||||
ALTER TABLE participations DROP COLUMN account_id;
|
||||
END IF;
|
||||
END $$;
|
||||
""")
|
||||
Reference in New Issue
Block a user