Здравствуйте! Я собираюсь создать бота для 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/> Подскажите, что может быть неправильно организовано или что стоит исправить?
При анализе вашего кода, я заметил несколько потенциальных источников ошибок, которые могут привести к `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(), а значит, гарантированно в одном рабочем цикле.