Ошибка "Unclosed client session" в aiohttp возникает, когда сессия клиента не закрыта после завершения работы с ним. Это может произойти, если вы создаете клиентские сессии без соответствующего закрытия.
В вашем случае вы используете `create_async_engine` и, вероятно, где-то в коде (может быть, в других частях вашего проекта или библиотеке) создаете сессию aiohttp, не закрывая ее. Давайте рассмотрим, как это можно исправить.
### 1. Убедитесь, что сессия закрыта
Если вы создаете клиентскую сессию предварительно, убедитесь, что вы закрываете ее после использования. Например:
```python
import aiohttp
async def fetch_data(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
```
### 2. Используйте контекстный менеджер с `AsyncEngine`
Если вы используете SQLAlchemy с `asyncio`, создайте `AsyncSession` с помощью контекстного менеджера:
```python
from sqlalchemy.ext.asyncio import AsyncSession
async by using the context manager when interacting with the database:
async with async_engine.begin() as conn:
async with AsyncSession(conn) as session:
# Ваш код для работы с результатами запроса
```
### 3. Отладьте и проверьте закрытие
Убедитесь, что все используемые вами клиентские сессии (aiohttp) закрываются в конце вашего приложения. Если вы создаете сессию на уровне модуля или приложения, вам может потребоваться убирать её из памяти, когда она больше не нужна.
### 4. Используйте функцию "shutdown" в ваших асинхронных приложениях
При завершении вашего приложения вы можете добавлять функцию "shutdown", которая будет закрывать все открытые сессии и соединения.
```python
async def shutdown():
# Закрываем любую глобальную сессию aiohttp
if hasattr(your_app, 'client_session'):
await your_app.client_session.close()
# Ваша точка входа
async def main():
try:
...
finally:
await shutdown()
```
### 5. Разделяйте ответственность
Рекомендуется создавать и закрывать `ClientSession` непосредственно в нужном месте, как показано выше, чтобы уменьшить шансы на "Unclosed client session".
### 6. Проверка других библиотек
Если вы используете библиотеки, которые зависят от aiohttp (например, для ботов, работающих с Telegram), убедитесь, что в них также управляется сессиями должным образом.
### Пример исправленного кода
Вот ваш исходный код с внесенными изменениями для обработки сессий:
```python
# engine.py
import aiohttp
async def create_async_engine(url: Union[URL, str]) -> AsyncEngine:
# Возможно, создание сессии здесь следует передать на уровень вызова
return _create_async_engine(url=url, echo=True, encoding='utf-8', pool_pre_ping=True)
# main.py
from aiohttp import ClientSession
async def main():
postgres_url = URL.create(...)
async_engine = await create_async_engine(postgres_url)
async with ClientSession() as session:
# Используйте сессию для ваших запросов
await proceed_schemas(async_engine, BaseModel.metadata)
await dp.start_polling(bot)
```
### Заключение
Убедитесь, что вы правильно закрываете все созданные сессии и используете подходящие контекстные менеджеры. Это поможет избежать ошибок, связанных с "Unclosed client session".