Как получить возвращаемые данные из асинхронных функций

Рейтинг: 0Ответов: 1Опубликовано: 26.01.2023

У меня есть несколько sql запросов и для них я сделал аналогичные функции:

async def get_from_table1():
    return pd.read_sql_query('SELECT * FROM [table1]', conn)

// conn - подключение к бд через sqlalchemy

Далее вызываю список функций следующим образом без ошибок и точно асинхронно(проверил по time):

async def main():
    await asyncio.gather(
        asyncio.create_task(view_to_pd.get_from_db_table1()),
        asyncio.create_task(view_to_pd.get_from_db_table2()),
        asyncio.create_task(view_to_pd.get_from_db_table3()),
        asyncio.create_task(view_to_pd.get_from_db_table4()),
        asyncio.create_task(view_to_pd.get_from_db_table5()),
        asyncio.create_task(view_to_pd.get_from_db_table6())
    )


asyncio.run(main())

Однако я не знаю как мне получить данных которые я возращаю. Как можно это сделать? Я новичок в асинхронном программировании. Извините за глупый вопрос.

Ответы

▲ 1Принят

В общем, благодаря пользователям andreymal и insolor +- разобрался в данном вопросе. Здесь воспользовался библиотекой aioodbc (бд у меня была mssql)

Первым делом я изменил функцию main:

async def main():
    res = await asyncio.gather(
        asyncio.create_task(view_to_pd.get_from_db_table1()),
        asyncio.create_task(view_to_pd.get_from_db_table2()),
        asyncio.create_task(view_to_pd.get_from_db_table3()),
        asyncio.create_task(view_to_pd.get_from_db_table4()),
        asyncio.create_task(view_to_pd.get_from_db_table5()),
        asyncio.create_task(view_to_pd.get_from_db_table6())
    )
return res

Однако теперь мне нужно преобразовать функции get_from_db_table в асинхронные. Т.к. у меня есть библиотека aioodbc, то я буду получать данные списком кортежей, а мне нужно вернуть DataFrame. Мне нужно было написать строчку:

await pd.DataFrame(rows, columns=columns)

Но она вызывает ошибку. Прошерстив немного интернет, я понял, что нет библиотеки для pandas, следовательно придется использовать костыльную функцию:

async def to_df(content, columns):
    return pd.DataFrame(np.array(content), columns=columns)

Тогда функции получения данных будет выглядеть следующим образом:

async def get_from_db_table1():
    loop = asyncio.get_event_loop()
    conn = await aioodbc.connect(dsn=conn_str, loop=loop)
    crs = await conn.cursor()
    await crs.execute("SELECT * FROM [table1]")
    rows = await crs.fetchall()
    await conn.close()
    res = await asyncio.gather(to_df(rows, columns=columns_table1]))
    return res[0]

Итого: на получение данных из 8-ми таблиц синхронным способом у меня ушло 15 секунд, а асинхронным 7 секунд!