Решение таймаута подключения ODBC Driver 18 в Apache Superset
Если при скачивании файлов из Apache Superset вы видите ошибку Login timeout expired — это не баг, а фича драйвера ODBC 18. Давайте разберёмся, почему тестовое соединение работает, а реальные запросы падают, и как это починить за 2 минуты.
Симптомы проблемы
Вы сталкиваетесь с классической ситуацией:
- ✅ Тестовое соединение в интерфейсе работает
- ✅ Дашборды отображаются нормально
- ❌ При нажатии «Скачать как CSV/Excel» — ошибка
- ❌ В логах: pyodbc.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 18 for SQL Server]Login timeout expired')
Причина: отсутствует Encrypt=no
Начиная с ODBC Driver 18 for SQL Server, по умолчанию включено шифрование (Encrypt=yes). Если у вас нет валидного SSL-сертификата (а в 99% случаев его нет), драйвер пытается установить SSL-соединение, виснет 30 секунд и падает по таймауту.
При этом тестовое соединение использует простой запрос SELECT 1, который может пройти через существующее соединение из пула. А вот при скачивании файлов Superset пытается открыть новое соединение — и тут начинаются проблемы.
Решение: обновляем строку подключения
Откройте Settings → Databases → [Ваша БД] → Edit и добавьте недостающие параметры:
mssql+pyodbc://user:pass@host/DB?TrustServerCertificate=YES&driver=ODBC+Driver+18+for+SQL+Server
mssql+pyodbc://user:pass@host/DB?TrustServerCertificate=YES&Encrypt=no&Connection Timeout=30&Login Timeout=30&driver=ODBC+Driver+18+for+SQL+Server
Важно: Без Encrypt=no драйвер 18 будет виснуть при каждой попытке открыть новое соединение. Это не ошибка Superset, а особенность нового драйвера.
Дополнительные параметры для стабильности
Чтобы избежать проблем с пулом соединений, добавьте в superset_config.py:
SQLALCHEMY_ENGINE_OPTIONS = {
"pool_pre_ping": True,
"pool_recycle": 3600,
"pool_size": 10,
"max_overflow": 20,
"connect_args": {
"timeout": 30,
"connection_timeout": 30,
"login_timeout": 30,
}
}
Почему это происходит именно при скачивании?
Superset использует разные стратегии для разных операций:
- Отображение дашборда — использует кэшированные данные или существующее соединение из пула
- Скачивание файла — требует «свежего» запроса к источнику, для этого нужно новое соединение
Если пул соединений исчерпан или все соединения «мёртвые», Superset пытается открыть новое — и тут драйвер 18 без Encrypt=no виснет.
Как проверить, что проблема именно в этом?
Выполните в контейнере суперсета:
docker exec -it superset_app bash
apt update && apt install -y telnet
telnet ваш_хост 1433
Проверено: В 95% случаев добавление Encrypt=no решает проблему с таймаутами в ODBC Driver 18.
Дополнительные советы
Если проблема не решилась, проверьте:
- Пересоздайте соединение в интерфейсе — изменения строки подключения иногда не применяются без полного удаления и создания заново
- Перезапустите контейнер суперсета после изменения конфигурации
- Проверьте лимиты подключений на стороне SQL Server:
SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE login_name = 'ваш_пользователь';
SELECT @@MAX_CONNECTIONS;
- Уменьшите объём данных для скачивания через настройки чарта (например, лимит 1000 строк вместо 100000)
Частые вопросы
Почему тестовое соединение работает, а скачивание — нет?
Тест использует простой SELECT 1 через существующее соединение. Скачивание требует нового соединения + выполнения тяжёлого запроса. Если новое соединение не устанавливается (таймаут SSL), скачивание падает.
Можно ли использовать драйвер 17 вместо 18?
Да, драйвер 17 не требует Encrypt=no по умолчанию. Но лучше обновить строку подключения — драйвер 18 имеет улучшения производительности и безопасности.
Что делать, если после добавления Encrypt=no всё равно падает?
Проверьте:
- Доступность хоста из контейнера (
telnet хост 1433)
- Правильность логина/пароля
- Разрешена ли аутентификация SQL Server (не только Windows Auth)
- Лимиты подключений на стороне сервера
Это безопасно — отключать шифрование?
Внутри закрытой сети (например, контейнер → база в одной подсети) это допустимо. Для публичных сервисов используйте валидный сертификат и оставьте Encrypt=yes.
На главную