Драйвер mssql-python определяет стандартную иерархию исключений, распространённые шаблоны обработки ошибок и отображения кода SQLSTATE для SQL Server и Azure SQL.
Иерархия исключений
Драйвер mssql-python следует иерархии исключений DB-API 2.0 (PEP 249):
Exception (builtins)
├── Warning
└── Error
├── InterfaceError
└── DatabaseError
├── DataError
├── OperationalError
├── IntegrityError
├── InternalError
├── ProgrammingError
└── NotSupportedError
ConnectionStringParseError (standalone, not part of hierarchy)
Описания исключений
Выберите самое конкретное исключение, которое соответствует вашей ситуации. Например, catch IntegrityError на нарушения ограничений на INSERT/UPDATE операциях и ProgrammingError для проблем с синтаксисом SQL во время разработки. Ловите базовый Error класс только как запасной вариант.
| Исключение |
При поднятии |
Warning |
Нефатальные предупреждения из базы данных. |
Error |
Базовый класс для всех ошибок базы данных. |
InterfaceError |
Ошибки касаются интерфейса базы данных (драйвера), а не самой базы данных. |
DatabaseError |
Ошибки, связанные с базой данных. |
DataError |
Ошибки, вызванные проблемами с обработанными данными (деление на ноль, значение вне диапазона). |
OperationalError |
Ошибки, связанные с работой с базой данных (потеря соединения, выделение памяти, ошибки транзакций). |
IntegrityError |
Ошибки при нарушении целостности базы данных (нарушение внешних ключей, уникальное ограничение). |
InternalError |
Внутренние ошибки базы данных (курсор некорректный, транзакция не синхронизирована). |
ProgrammingError |
Ошибки программирования (синтаксические ошибки, таблица не найдена, неправильное количество параметров). |
NotSupportedError |
Функция не поддерживается базой данных или драйвером. |
ConnectionStringParseError |
Некорректный синтаксис строка подключения или неизвестные ключевые слова. |
Базовая обработка ошибок
Используйте блоки try-except для обработки ошибок базы данных:
import mssql_python
try:
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
cursor.execute("INSERT INTO Production.Product (Name) VALUES (%(name)s)", {"name": "Test"})
conn.commit()
except mssql_python.IntegrityError as e:
print(f"Constraint violation: {e}")
conn.rollback()
except mssql_python.ProgrammingError as e:
print(f"SQL syntax error: {e}")
except mssql_python.OperationalError as e:
print(f"Connection or operational error: {e}")
except mssql_python.Error as e:
print(f"Database error: {e}")
finally:
if 'conn' in locals():
conn.close()
Исключения доступа через соединение
Вы можете обназначить исключения через экземпляр соединения:
try:
cursor.execute("INVALID SQL")
except conn.ProgrammingError as e:
print(f"Caught via connection: {e}")
Структура сообщений об ошибке
Объекты исключений MSSQL-Python предоставляют три атрибута, полученные из базового классаException драйвера:
| Атрибут |
Source |
Описание |
driver_error |
Python-драйвер |
Стандартизированный английский текст, выбранный SQLSTATE, возвращался из ODBC (например, "Communication link failure", "Invalid authorization specification", "Syntax error or access violation"). Стабильно на всех релизах; безопасно сопоставлять субструны. |
ddbc_error |
Прямое подключение к базе данных (DDBC) |
Серверное сообщение, обычно с префиксом [Microsoft][SQL Server]. Формат — это нестабильный контракт. |
message |
Сформирован |
f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". Вот что str(exc) возвращается. |
try:
cursor.execute("SELECT * FROM no_such_table;")
except mssql_python.ProgrammingError as exc:
print(exc.driver_error) # Base table or view not found
print(exc.ddbc_error) # [Microsoft][SQL Server]Invalid object name 'no_such_table'.
print(exc) # Driver Error: Base table or view not found; DDBC Error: ...
Номер ошибки движка SQL Server (например208, или 40501) не отображается как атрибут и не надёжно встроен ни в одну строку. Классифицируйте ошибки по подклассу исключений плюс driver_error тексту. Для Azure SQL throttling см. Retry logic.
Классификация SQLSTATE
mssql-python использует SQLSTATE, возвращаемый ODBC, для выбора как подкласса исключений Python, так и текстаdriver_error. Полное отображение исключений → SQLSTATE находится exceptions.py в исходном коде драйвера. В следующем разделе перечислены SQLSTATE, которые чаще всего встречаются с SQL Server и Azure SQL.
Ошибки подключения
Сбои соединения из-за mssql_python.connect() повышения mssql_python.OperationalError, такие же, как и при других сбоях подключения:
import mssql_python
try:
conn = mssql_python.connect(
"Server=unreachable-server.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes"
)
except mssql_python.OperationalError as e:
print(f"Connection failed: {e.driver_error}")
# e.driver_error: "Client unable to establish connection"
Ошибки строки подключения
Ошибки разбора строк соединения вызывают ConnectionStringParseError:
try:
conn = mssql_python.connect("Servr=localhost;") # Typo
except mssql_python.ConnectionStringParseError as e:
print(f"Invalid connection string: {e}")
# Output: Unknown keyword 'Servr'
Ссылка на код SQLSTATE
Коды SQLSTATE — это пятисимвольные коды, которые определяют условия ошибок. Первые два символа обозначают класс, а последние три — подкласс. Редко приходится проверять эти коды напрямую. Вместо этого зафиксируйте соответствующий тип исключения Python (указанный в столбце «Исключение»). Используйте коды SQLSTATE, когда нужно различать конкретные ошибки внутри одного типа исключения, например, чтобы отличить тупиковую блокировку (40001) от общего сбоя соединения (08S01).
Класс 00 — успешное завершение
| SQLSTATE |
Исключение |
Описание |
| 00000 |
Нет |
Success |
Класс 01 — Предупреждение
| SQLSTATE |
Исключение |
Описание |
| 01000 |
Предупреждение |
Общее предупреждение |
| 01001 |
Предупреждение |
Конфликт операций курсора |
| 01002 |
Предупреждение |
Ошибка отключения |
| 01003 |
DataError |
Значение NULL, устраненное в функции set |
| 01004 |
DataError |
Строковые данные, усечение справа |
| 01006 |
Предупреждение |
Привилегии не отозваны |
| 01007 |
Предупреждение |
Привилегии не предоставлены |
| 01S00 |
Предупреждение |
Недопустимый атрибут строка подключения |
| 01S01 |
Предупреждение |
Ошибка в строке |
| 01S02 |
Предупреждение |
Изменено значение параметра |
Класс 07 — Динамическая ошибка SQL
| SQLSTATE |
Исключение |
Описание |
| 07001 |
ProgrammingError |
Неправильное количество параметров |
| 07002 |
ProgrammingError |
Неправильное поле COUNT |
| 07005 |
ProgrammingError |
Подготовленный оператор, а не курсорная спецификация |
| 07006 |
ProgrammingError |
Нарушение атрибута ограниченного типа данных |
| 07009 |
ProgrammingError |
Индекс некорректного дескриптора |
| 07S01 |
ProgrammingError |
Недопустимое использование параметра по умолчанию |
Класс 08 — исключение при соединении
| SQLSTATE |
Исключение |
Описание |
| 08001 |
OperationalError |
Клиенту не удается установить подключение |
| 08002 |
OperationalError |
Имя подключения, используемое |
| 08003 |
OperationalError |
Связи отсутствует |
| 08004 |
OperationalError |
Сервер отклонил подключение |
| 08007 |
OperationalError |
Сбой соединения во время транзакции |
| 08S01 |
OperationalError |
Сбой связи |
Класс 21 — нарушение кардинальности
| SQLSTATE |
Исключение |
Описание |
| 21S01 |
ProgrammingError |
Список значений не соответствует списку столбцов |
| 21S02 |
ProgrammingError |
Степень производной таблицы не соответствует списку столбцов |
Класс 22 — исключение данных
| SQLSTATE |
Исключение |
Описание |
| 22001 |
DataError |
Строковые данные, усечение справа |
| 22002 |
DataError |
Переменная индикатора, требуемая, но не указанная |
| 22003 |
DataError |
Числовое значение вне диапазона |
| 22007 |
DataError |
Недопустимый формат datetime |
| 22008 |
DataError |
Переполнение поля Datetime |
| 22012 |
DataError |
Деление по нулю |
| 22015 |
DataError |
Переполнение поля интервала |
| 22018 |
DataError |
Недопустимое значение символа для спецификации приведения |
| 22019 |
DataError |
Недопустимый escape-символ |
| 22025 |
DataError |
Недопустимая последовательность escape-адресов |
| 22026 |
DataError |
Строковые данные, несовпадение длины |
Класс 23 — нарушение ограничений целостности
| SQLSTATE |
Исключение |
Описание |
| 23000 |
IntegrityError |
Нарушение ограничения целостности (общее) |
Класс 24 — недопустимое состояние курсора
| SQLSTATE |
Исключение |
Описание |
| 24000 |
Внутренняя ошибка |
Недопустимое состояние курсора |
Класс 25 — недопустимое состояние транзакции
| SQLSTATE |
Исключение |
Описание |
| 25000 |
OperationalError |
Недопустимое состояние транзакции |
| 25S01 |
OperationalError |
Состояние транзакции неизвестно |
| 25S02 |
OperationalError |
Транзакция всё ещё активна |
| 25S03 |
OperationalError |
Транзакция откатывается |
Класс 28 — Недействительная спецификация авторизации
| SQLSTATE |
Исключение |
Описание |
| 28000 |
OperationalError |
Неверная спецификация авторизации (вход не выполнен) |
Класс 34 — неверное имя курсора
| SQLSTATE |
Исключение |
Описание |
| 34000 |
ProgrammingError |
Недопустимое имя курсора |
Класс 3C — дублирует имя курсора
| SQLSTATE |
Исключение |
Описание |
| 3C000 |
ProgrammingError |
Повторяющееся имя курсора |
Класс 3D — неверное название каталога
| SQLSTATE |
Исключение |
Описание |
| 3D000 |
ProgrammingError |
Недопустимое имя каталога |
Класс 3F — неверное имя схемы
| SQLSTATE |
Исключение |
Описание |
| 3F000 |
ProgrammingError |
Недопустимое имя схемы |
Класс 40 — откат транзакций
| SQLSTATE |
Исключение |
Описание |
| 40001 |
OperationalError |
Сбой сериализации (тупик) |
| 40002 |
OperationalError |
Нарушение ограничения целостности вызывало откат |
| 40003 |
OperationalError |
Неизвестное завершение инструкции |
Класс 42 — ошибка в синтаксисе или нарушение правил доступа
| SQLSTATE |
Исключение |
Описание |
| 42000 |
ProgrammingError |
Синтаксическая ошибка или нарушение доступа |
| 42S01 |
ProgrammingError |
Базовая таблица или представление уже существует |
| 42S02 |
ProgrammingError |
Базовая таблица или представление не найдено |
| 42S11 |
ProgrammingError |
Индекс уже существует |
| 42S12 |
ProgrammingError |
Индекс не найден |
| 42S21 |
ProgrammingError |
Столбец уже существует |
| 42S22 |
ProgrammingError |
Столбец не найден |
Класс 44 — С НАРУШЕНИЕМ ОПЦИИ CHECK
| SQLSTATE |
Исключение |
Описание |
| 44000 |
IntegrityError |
Нарушение параметра WITH CHECK OPTION |
Класс HY — специфическое для CLI состояние
| SQLSTATE |
Исключение |
Описание |
| HY000 |
DatabaseError |
Общая ошибка |
| HY001 |
OperationalError |
Ошибка выделения памяти |
| HY003 |
ProgrammingError |
Недопустимый тип буфера приложения |
| HY004 |
ProgrammingError |
Недопустимый тип данных SQL |
| HY007 |
ProgrammingError |
Связанная инструкция не подготовлена |
| HY008 |
OperationalError |
Операция отменена |
| HY009 |
ProgrammingError |
Недопустимое использование указателя NULL |
| HY010 |
ProgrammingError |
Ошибка последовательности функций |
| HY011 |
ProgrammingError |
Атрибут не может быть задан сейчас |
| HY012 |
ProgrammingError |
Некорректный код операции транзакции |
| HY013 |
OperationalError |
Ошибка управления памятью |
| HY014 |
OperationalError |
Лимит на превышение количества ручок |
| HY015 |
ProgrammingError |
Имя курсора недоступно |
| HY016 |
ProgrammingError |
Нельзя изменить дескриптор строки реализации |
| HY017 |
ProgrammingError |
Некорректное использование автоматически выделенного дескриптора |
| HY018 |
OperationalError |
Сервер отклонил запрос на отмену |
| HY019 |
ProgrammingError |
Несимвольные и небинарные данные, передаваемые частями |
| HY020 |
DataError |
Попытка конкатенировать нулевое значение |
| HY021 |
ProgrammingError |
Несогласованная информация о описаниях |
| HY024 |
ProgrammingError |
Недопустимое значение атрибута |
| HY090 |
ProgrammingError |
Недопустимая длина строки или буфера |
| HY091 |
ProgrammingError |
Идентификатор поля некорректного дескриптора |
| HY092 |
ProgrammingError |
Некорректный идентификатор атрибута/опции |
| HY095 |
ProgrammingError |
Тип функции вне зоны действия |
| HY096 |
ProgrammingError |
Некорректный тип информации |
| HY097 |
ProgrammingError |
Тип колонки вне зоны действия |
| HY098 |
ProgrammingError |
Тип прицела вне зоны действия |
| HY099 |
ProgrammingError |
Обнулируемый тип вне зоны действия |
| HY100 |
ProgrammingError |
Тип параметра Uniqueness вне диапазона |
| HY101 |
ProgrammingError |
Тип параметра точности вне диапазона |
| HY103 |
ProgrammingError |
Некорректный код поиска |
| HY104 |
ProgrammingError |
Недопустимое значение точности или масштабирования |
| HY105 |
ProgrammingError |
Недопустимый тип параметра |
| HY106 |
ProgrammingError |
Тип апорта вне зоны действия |
| HY107 |
ProgrammingError |
Значение строки вне зоны действия |
| HY109 |
ProgrammingError |
Недопустимое положение курсора |
| HY110 |
ProgrammingError |
Неверное завершение драйвера |
| HY111 |
ProgrammingError |
Неверное значение закладок |
| HYC00 |
NotSupportedError |
Необязательный компонент не реализован |
| HYT00 |
OperationalError |
Время ожидания истекло. |
| HYT01 |
OperationalError |
Время ожидания для подключения истекло |
Класс IM — ошибка менеджера водителя
| SQLSTATE |
Исключение |
Описание |
| IM001 |
InterfaceError |
Драйвер не поддерживает эту функцию |
| IM002 |
InterfaceError |
Имя источника данных не найдено |
| IM003 |
InterfaceError |
Не удалось загрузить указанный драйвер |
| IM004 |
InterfaceError |
SQLAllocHandle драйвера на SQL_HANDLE_ENV неудача |
| IM005 |
InterfaceError |
Драйвер SQLAllocHandle на SQL_HANDLE_DBC не сработал |
| IM006 |
InterfaceError |
SQLSetConnectAttr драйвера не сработал |
| IM007 |
InterfaceError |
Источник данных или драйвер не указаны |
| IM008 |
InterfaceError |
Диалог провалился |
| IM009 |
InterfaceError |
Не удалось загрузить библиотеку DLL перевода |
| IM010 |
InterfaceError |
Слишком длинное имя источника данных |
| IM011 |
InterfaceError |
Слишком длинное имя драйвера |
| IM012 |
InterfaceError |
Ошибка синтаксиса ключевого слова DRIVER |
| IM014 |
InterfaceError |
Неверный DSN |
| IM015 |
InterfaceError |
Повреждённый источник данных файлов |
Распространённые номера ошибок SQL Server
Помимо SQLSTATE, SQL Server предоставляет нативные номера ошибок в скобках. Это те ошибки, с которыми вы чаще всего столкнётесь в коде приложений. Постройте логику повторных попыток вокруг ошибки 1205 (тупик) и временных ошибок соединения (см. логику повторного использования).
| Ошибка |
Шаблон сообщения |
Разрешение |
| 208 |
Недопустимое имя объекта |
Проверьте, существует ли таблица или представление, и проверьте квалификацию схемы. |
| 547 |
Нарушение ограничений |
Внешний ключ или ограничение проверки не сработали. |
| 2627 |
Нарушение уникального ограничения |
Вставлялось дублирующее значение ключа. |
| 2601 |
Нарушение уникального индекса |
В индексе существует дублирующий ключ. |
| 4060 |
Нельзя открыть базу данных |
База данных не существует, или доступ запрещён. |
| 18456 |
Сбой входа |
Ошибка аутентификации. Проверьте учетные данные. |
| 1205 |
Жертва взаимоблокировки |
Выполнен откат этой транзакции. Повторите операцию. |
Краткая справка по принципу «симптом к исключению»
Используйте эту таблицу, чтобы сопоставить распространённые симптомы с типом исключения, которые вам следует заметить:
| Симптом |
Исключение |
Вероятная причина |
| «Неудачный вход для пользователя» |
OperationalError |
Неправильные учетные данные или пользователь не связан с базой данных. |
| "Клиент не может установить соединение" |
OperationalError |
Сервер недоступен, файрвол или проблема с DNS. |
| «Тайм-аут истек» |
OperationalError |
Тайм-аут запроса или соединения. Увеличьте тайм-аут или оптимизируйте запросы. |
| «Неверное имя объекта» |
ProgrammingError |
Таблица не существует, или схема не указана. |
| «Неправильный синтаксис» |
ProgrammingError |
Ошибка в синтаксисе SQL. Тестовый запрос в SSMS. |
| «Неправильное количество параметров» |
ProgrammingError |
Количество параметров не совпадает с заглушками. |
| "Нарушение ПЕРВИЧНОГО КЛЮЧА" |
IntegrityError |
Дубликат ключа. Используйте MERGE или проверьте перед введением. |
| «Нарушение ИНОСТРАННОГО КЛЮЧА» |
IntegrityError |
Упомянутый ряд не существует. Сначала вставьте родителя. |
| «Сделка была заблокирована» |
OperationalError (ошибка 1205) |
Спор на замок. Реализуйте логику повторных попыток. |
| «Строковые или двоичные данные будут усечаны» |
DataError |
Значение превышает длину столбца. Проверьте данные или увеличите размер столбцов. |
| «Конверсия не удалась» |
DataError |
Несоответствие типов. Используйте правильный тип Python для столбца. |
| «Неизвестное ключевое слово» |
ConnectionStringParseError |
Опечатка в ключевом слове строка подключения. |
| «callproc не поддерживается» |
NotSupportedError |
Вместо этого используйте cursor.execute("EXECUTE ..."). |
Лучшие практики
-
Ловите конкретные исключения перед обычными. Порядок от самого конкретного (
IntegrityError) к наименее конкретному (Error).
-
Всегда обрабатывайте IntegrityError для операций модификации данных. Нарушения ограничений ожидаются в обычной работе (например, если пользователь пытается создать дублирующееся имя пользователя).
-
Запишите полный контекст ошибок для устранения неполадок. Исключение включает
driver_error (стабильный, SQLSTATE-производный текст) и ddbc_error (серверное сообщение). Записывайте оба; классифицировать на driver_error.
-
Реализуйте повторную логику для временных ошибок (сбои соединения, тупиковые блокировки). См. логику повторного попытки.
-
Используйте rollback() в обработчиках exception для очистки неудачных транзакций. Без явного отката соединение остаётся в состоянии неудачной транзакции.
Связанные материалы