Files
new_lottery_bot/docs/POSTGRESQL_MIGRATION.md
2025-11-16 12:36:02 +09:00

4.6 KiB
Raw Blame History

# Миграция на PostgreSQL

## Выполненные изменения

### 1. Настройка подключения

В файле `.env` раскомментирована строка:
```env
DATABASE_URL=postgresql+asyncpg://trevor:R0sebud@192.168.0.102/bot_db
```

### 2. Создание базы данных

```bash
psql -h 192.168.0.102 -U trevor -d postgres -c "CREATE DATABASE bot_db;"
```

### 3. Инициализация таблиц

Вместо Alembic-миграций (из-за проблем с длинными именами версий) используется прямое создание:
```bash
. .venv/bin/activate && python -c "import asyncio; from database import init_db; asyncio.run(init_db())"
```

### 4. Исправление бага в services.py

Добавлен параметр `limit` в метод `LotteryService.get_active_lotteries()`:

```python
@staticmethod
async def get_active_lotteries(session: AsyncSession, limit: Optional[int] = None) -> List[Lottery]:
    """Получить список активных розыгрышей"""
    query = select(Lottery).where(
        Lottery.is_active == True, 
        Lottery.is_completed == False
    ).order_by(Lottery.created_at.desc())
    
    if limit:
        query = query.limit(limit)
    
    result = await session.execute(query)
    return result.scalars().all()
```

## Различия SQLite vs PostgreSQL

| Параметр | SQLite | PostgreSQL |
|----------|--------|------------|
| Тип ID | `INTEGER` | `SERIAL` |
| Datetime | `DATETIME` | `TIMESTAMP WITHOUT TIME ZONE` |
| JSON | `JSON` (текст) | `JSON` (нативный тип) |
| Транзакции | Автоматические | Явные BEGIN/COMMIT |

## Проверка подключения

```bash
psql -h 192.168.0.102 -U trevor -d bot_db -c "\dt"
```

## Структура таблиц в PostgreSQL

```sql
-- Пользователи
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    telegram_id INTEGER UNIQUE NOT NULL,
    username VARCHAR(255),
    first_name VARCHAR(255),
    last_name VARCHAR(255),
    created_at TIMESTAMP,
    is_admin BOOLEAN,
    account_number VARCHAR(23) UNIQUE
);

-- Розыгрыши
CREATE TABLE lotteries (
    id SERIAL PRIMARY KEY,
    title VARCHAR(500) NOT NULL,
    description TEXT,
    created_at TIMESTAMP,
    start_date TIMESTAMP,
    end_date TIMESTAMP,
    is_active BOOLEAN,
    is_completed BOOLEAN,
    prizes JSON,
    creator_id INTEGER REFERENCES users(id),
    manual_winners JSON,
    draw_results JSON,
    winner_display_type VARCHAR(20)
);

-- Участия
CREATE TABLE participations (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES users(id),
    lottery_id INTEGER NOT NULL REFERENCES lotteries(id),
    account_number VARCHAR(23),
    created_at TIMESTAMP
);
CREATE INDEX ix_participations_account_number ON participations(account_number);

-- Победители
CREATE TABLE winners (
    id SERIAL PRIMARY KEY,
    lottery_id INTEGER NOT NULL REFERENCES lotteries(id),
    user_id INTEGER REFERENCES users(id),
    account_number VARCHAR(23),
    place INTEGER NOT NULL,
    prize VARCHAR(500),
    is_manual BOOLEAN,
    created_at TIMESTAMP
);
CREATE INDEX ix_winners_account_number ON winners(account_number);
```

## Резервное копирование

### Создание бэкапа
```bash
pg_dump -h 192.168.0.102 -U trevor -d bot_db > backup.sql
```

### Восстановление из бэкапа
```bash
psql -h 192.168.0.102 -U trevor -d bot_db < backup.sql
```

## Сброс базы данных

```bash
psql -h 192.168.0.102 -U trevor -d postgres << 'EOF'
DROP DATABASE IF EXISTS bot_db;
CREATE DATABASE bot_db;
EOF
```

Затем:
```bash
. .venv/bin/activate && python -c "import asyncio; from database import init_db; asyncio.run(init_db())"
```

## Статус миграции

✅ База данных: PostgreSQL  
✅ Таблицы созданы  
✅ Индексы настроены  
✅ Бот запущен и работает  
✅ Исправлена ошибка с `limit` параметром  

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

Теперь бот готов к тестированию:

1. **Создайте тестовый розыгрыш** через админ-панель
2. **Отправьте счет** боту в формате `11-22-33-44-55-66-77-88`
3. **Проверьте inline-меню** - должны появиться кнопки действий
4. **Добавьте счета** в розыгрыш
5. **Установите победителя** по счету

Все данные теперь хранятся в PostgreSQL на `192.168.0.102`!