Я пытаюсь создать бота для Telegram, но сталкиваюсь с ошибкой RuntimeError. Как можно решить эту проблему?

Здравствуйте! Я собираюсь создать бота для Telegram и нуждаюсь в вашей помощи, чтобы разобраться с возникшими проблемами. Ниже приведён код из файла main.py: <br/> <pre><code>import logging
import asyncio

from aiogram import Bot, Dispatcher, F
from settings.config import TOKEN
from aiogram.filters import Command
from aiogram.types import ContentType, Message
from database.register import datebase

logging.basicConfig(level=logging.INFO)
bot = Bot(token=TOKEN)
dp = Dispatcher()

@dp.message(F.content_type == ContentType.TEXT)
async def start(message: Message):
   user_id = message.from_user.id
   username = message.from_user.username
   name = await datebase().register(user_id, username)
   print(name)

async def main():
   await dp.start_polling(bot)

if __name__ == "__main__":
   try:
      asyncio.run(main())
   except KeyboardInterrupt:
      print('Error')</code></pre> <br/> <br/> А вот код из файла register.py: <br/> <pre><code>import time
from datetime import date

from aiomysql import Pool
from database.connection import db_pool

registration_date = date.today()
Working_hours = time.strftime("%H:%M:%S")

class datebase():
    pool: Pool = db_pool
    
    async def register(self, user_id, username):
        async with self.pool.acquire() as conn:
            async with conn.cursor() as cur:
                result = await cur.execute("SELECT * FROM TGProfiles WHERE uid=%s", user_id)
                row = await cur.fetchall()
                if result == 0:
                    await cur.execute("INSERT INTO TGProfiles(uid, name, DateRegister) VALUES (%s, %s, %s)", (user_id, username, registration_date))
                else:
                    return row</code></pre> <br/> <br/> Подскажите, что может быть неправильно организовано или что стоит исправить?
  • 27 ноября 2024 г. 20:53
Ответы на вопрос 2
При анализе вашего кода, я заметил несколько потенциальных источников ошибок, которые могут привести к `RuntimeError`. Давайте рассмотрим основные моменты:

1. **Использование `aiogram`**: Вы правильно импортируете необходимые модули и функции, но важно убедиться, что ваш бот и все используемые ресурсы корректно инициализированы.

2. **Регистрация обработчиков**: Вы не зарегистрировали обработчик сообщения в диспетчере (`dp`). Это можно сделать, добавив `dp.include_router(...)`, или прямо регистрируя функции с помощью декораторов, например:
   ```python
   @dp.message_handler(content_types=[ContentType.TEXT])
   async def start(message: Message):
       ...
   ```

3. **Создание пула базы данных**: Убедитесь, что `db_pool` инициализирован до его использования. Если `db_pool` не инициализирован или возвращает `None`, это может вызвать `RuntimeError`. Обычно создание пула выполняется в асинхронной функции.

4. **Обработка исключений**: Запишите более детализированное исключение, чтобы понять, где именно происходит ошибка. Например, вы можете обернуть ваш `asyncio.run(main())` в более общий блок try-except:
   ```python
   if __name__ == "__main__":
       try:
           asyncio.run(main())
       except Exception as e:
           logging.exception("An error occurred")
   ```

5. **Проверка зависимости от <code>aiomysql</code>**: Убедитесь, что библиотека <code>aiomysql</code> корректно установлена и работает с вашей версией Python. Часто используемые проблемы связаны с версионированием и несовместимостью между библиотеками.

6. **Инициализация базы данных**: Убедитесь, что ваши методы работы с базой данных правильно инициализированы до вызова их в функции. Возможно, стоит явно создать асинхронную функцию для инициализации пула:

```python
async def init_db():
    global db_pool
    db_pool = await aiomysql.create_pool(...)
```

7. **Логирование**: Вставьте больше логов в процессе выполнения (например, перед выполнением запросов к БД) для лучшего понимания, на какой части кода возникает ошибка.

Если вы все еще получаете `RuntimeError`, предоставьте конкретное сообщение об ошибке и информацию о том, где именно ошибка возникает, чтобы помочь поищем решение более детально.
Без агрессии нельзя, это же интернет. Если тут не посылают, значит, что-то стряслось. =) 

Основой асинхронной программы является рабочий цикл (event loop). Он должен быть строго один. Я подозреваю, что у тебя создаётся более одного рабочего цикла, так как ты делаешь несколько вызовов get_event_loop() в придачу к asyncio.run().

Я бы изменил код следующим образом: пусть класс базы данных принимает пул соединений как параметр конструктора. Аналогично, создай в основном файле глобальную переменную, которая будет хранить экземпляр этого класса. При создании присвой переменной None.

А вот внутри main() уже делай всё остальное: создай экземпляр пула соединений, создать экземпляр класса БД (и закинь его в глобальную переменную), а потом запускай бота. Тогда у тебя все асинхронные операции будут происходить в рамках одного вызова main(), а значит, гарантированно в одном рабочем цикле.
Похожие вопросы