Как получить возвращаемые данные из асинхронных функций
У меня есть несколько 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 секунд!