163 lines
4.6 KiB
Markdown
163 lines
4.6 KiB
Markdown
````markdown
|
||
# Миграция на 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`!
|
||
|
||
```` |