Files
new_lottery_bot/POSTGRESQL_MIGRATION.md
2025-11-15 20:03:49 +09:00

4.6 KiB
Raw Blame History

Миграция на PostgreSQL

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

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

В файле .env раскомментирована строка:

DATABASE_URL=postgresql+asyncpg://trevor:R0sebud@192.168.0.102/bot_db

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

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

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

Вместо Alembic-миграций (из-за проблем с длинными именами версий) используется прямое создание:

. .venv/bin/activate && python -c "import asyncio; from database import init_db; asyncio.run(init_db())"

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

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

@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

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

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

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

-- Пользователи
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);

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

Создание бэкапа

pg_dump -h 192.168.0.102 -U trevor -d bot_db > backup.sql

Восстановление из бэкапа

psql -h 192.168.0.102 -U trevor -d bot_db < backup.sql

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

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

Затем:

. .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!