Асинхронная база данных в связке с aiohttp и aiogram

Мне необходимо одновременно работать с ботом и обрабатывать кастомные вебхуки, для этого я использую стандартный пример aiogram. Я пытаюсь добавить асинхронную базу данных, чтобы доступ можно было получать и из бота, и из routes для этого я использую asyncpg и создаю pool соединений следующим образом:

main.py:

async def init_db(app):
    """Initialize a connection pool."""
    app["pool"] = await asyncpg.create_pool(database="postgres", user="postgres")
    yield
    app["pool"].close()


def main():
    bot = Bot(token=TOKEN, parse_mode="HTML")
    dispatcher = Dispatcher()
    dispatcher["base_url"] = APP_BASE_URL
    dispatcher.startup.register(on_startup)

    dispatcher.include_router(bot_router)

    app = Application()
    app["bot"] = bot
    app.cleanup_ctx.append(init_db)

    app.router.add_post("/amo_crm/", amo_message_handler)
    SimpleRequestHandler(
        dispatcher=dispatcher,
        bot=bot,
    ).register(app, path="/webhook")
    setup_application(app, dispatcher, bot=bot)

    run_app(app, host="127.0.0.1", port=8081)

routes.py:

async def handle(request):
    pool = request.app["pool"]
    power = int(request.match_info.get("power", 10))

    # Take a connection from the pool.
    async with pool.acquire() as connection:
        # Open a transaction.
        async with connection.transaction():
            # Run the query passing the request argument.
            result = await connection.fetchval("select 2 ^ $1", power)
            return json_response(text="2 ^ {} is {}".format(power, result))


async def amo_message_handler(request: Request):
    data = await request.post()
    bot: Bot = request.app["bot"]
    await bot.send_message(chat_id, "TEST")

handlers.py:

bot_router = Router()


@bot_router.message(Command("start"))
async def command_start(message: Message, bot: Bot, base_url: str):
    await message.answer("TEST")

Это работает для routes, но как мне корректно подключаться к базе данных из бота (handlers.py)?


Ответы (1 шт):

Автор решения: Medvedev

Обычное подключение к БД:

# подкючаемся
connection = psycopg2.connect(
            host=config.ip, # localhost или иной адрес 
            user=config.PGUSER, # имя пользователя от которого бот будет работать в БД
            password=config.PGPASSWORD, # пароль
            database=config.DATABASE # имя вашей БД
        )

А далее все необходимые запросы:

cursor = connection.cursor()
# по этому шаблону любой запрос в psql можете направлять
cursor.execute("SELECT * FROM information_schema.tables WHERE table_name = %s", ('users',)) 
result = cursor.fetchone()

Вставляете функции с запросами в бота и бот их будет обрабатывать согласно вашим инструкциям

Забыл про самое главное, для работы с psql используется библиотека psycopg2

→ Ссылка