Превращение синхронного кода в асинхронный python
Я очень часто использую асинхронность в python, но обычно всё сводится к вызовам асинхронных функций в каких-либо библиотеках (например aiohttp).
Меня уже давно мучает вопрос: как синхронный код превращается в асинхронный? Я знаю про планировщик, корутины, генераторы и т.д, но не могу понять как всё это работает изнутри и как я могу асинхронно ожидать выполнения синхронной функции.
Кратко о задаче: нужно асинхронно сделать запрос в базу. Конечно, есть асинхронные библиотеки, но для примера предположим, что таковых не нашлось
async def foo():
...
cursor.execute(query) # Синхронная функция, которая посылает запрос
Как я с помощью asyncio я могу сказать "Подожди пока эта функция выполнится, а пока делай что-нибудь другое".