O driver mssql-python define uma hierarquia padrão de exceções, padrões comuns de tratamento de erros e mapeamentos de código SQLSTATE para SQL Server e SQL do Azure.
Hierarquia de exceções
O driver mssql-python segue a hierarquia de exceções DB-API 2.0 (PEP 249):
Exception (builtins)
├── Warning
└── Error
├── InterfaceError
└── DatabaseError
├── DataError
├── OperationalError
├── IntegrityError
├── InternalError
├── ProgrammingError
└── NotSupportedError
ConnectionStringParseError (standalone, not part of hierarchy)
Descrições de exceções
Observe a exceção mais específica que combine com a sua situação. Por exemplo, detectar IntegrityError violações de restrições em INSERToperaçõesUPDATE / e ProgrammingError para problemas de sintaxe SQL durante o desenvolvimento. Pegue a classe base Error apenas como plano B.
| Exceção |
Quando gerado |
Warning |
Avisos não fatais do banco de dados. |
Error |
Classe base para todos os erros de banco de dados. |
InterfaceError |
Erros relacionados à interface do banco de dados (driver), não ao banco de dados em si. |
DatabaseError |
Erros relacionados ao banco de dados. |
DataError |
Erros devido a problemas com dados processados (divisão por zero, valor fora do intervalo). |
OperationalError |
Erros relacionados à operação do banco de dados (perda de conexão, alocação de memória, erros de transação). |
IntegrityError |
Erros quando a integridade do banco de dados é afetada (violação de chave estrangeira, restrição única). |
InternalError |
Erros internos do banco de dados (cursor não válido, transação fora de sincronia). |
ProgrammingError |
Erros de programação (erros de sintaxe, tabela não encontrada, número errado de parâmetros). |
NotSupportedError |
Recurso não suportado pelo banco de dados ou pelo driver. |
ConnectionStringParseError |
Sintaxe inválida de cadeia de conexão ou palavras-chave desconhecidas. |
Tratamento básico de erros
Use blocos try-except para lidar com erros de banco de dados:
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()
Exceções de acesso através da conexão
Você pode detectar exceções através da instância de conexão:
try:
cursor.execute("INVALID SQL")
except conn.ProgrammingError as e:
print(f"Caught via connection: {e}")
Estrutura da mensagem de erro
Objetos de exceção MSSQL-Python expõem três atributos que vêm da classe base doException driver:
| Attribute |
Source |
Descrição |
driver_error |
Driver Python |
Texto padronizado em inglês escolhido pelo SQLSTATE retornou do ODBC (por exemplo, "Communication link failure", "Invalid authorization specification", "Syntax error or access violation"). Estável entre os lançamentos; Seguro para substring match. |
ddbc_error |
Conectividade Direta com Banco de Dados (DDBC) |
A mensagem do lado do servidor, normalmente com o prefixo [Microsoft][SQL Server]. O formato não é um contrato estável. |
message |
Composto |
f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". É isso que str(exc) retorna. |
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: ...
O número de erro do motor do SQL Server (como 208 ou 40501) não é exposto como um atributo e não está embutido de forma confiável em nenhuma das strings. Classificar erros por subclasse de exceção mais driver_error texto. Para a limitação do SQL do Azure, veja Lógica de tentativa.
Classificação SQLSTATE
mssql-python usa o SQLSTATE retornado pelo ODBC para escolher tanto a subclasse de exceção Python quanto o driver_error texto. O mapeamento completo de SQLSTATE → exceções está no exceptions.py código-fonte do driver. A próxima seção lista os SQLSTATEs que aparecem com mais frequência no SQL Server e no SQL do Azure.
Erros de conexão
Falhas de conexão do mssql_python.connect() raise mssql_python.OperationalError, iguais a outras falhas de conectividade:
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"
Erros na cadeia de conexão
Erros de análise de string de conexão levantam 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'
Referência de código SQLSTATE
Os códigos SQLSTATE são códigos de cinco caracteres que identificam condições de erro. Os dois primeiros caracteres indicam a classe, e os três últimos indicam a subclasse. Você raramente precisa inspecionar esses códigos diretamente. Em vez disso, observe o tipo de exceção Python apropriado (listado na coluna "Exceção"). Use códigos SQLSTATE quando precisar distinguir entre condições de erro específicas dentro do mesmo tipo de exceção, por exemplo, para diferenciar um deadlock (40001) de uma falha geral de conexão (08S01).
Classe 00 - Conclusão bem-sucedida
| SQLSTATE |
Exceção |
Descrição |
| 00000 |
None |
Êxito |
Classe 01 - Aviso
| SQLSTATE |
Exceção |
Descrição |
| 01000 |
Warning |
Aviso geral |
| 01001 |
Warning |
Conflito de operação do cursor |
| 01002 |
Warning |
Erro de desconexão |
| 01003 |
DataError |
Valor NULL eliminado na função set |
| 01004 |
DataError |
Dados de cadeia de caracteres, truncamento à direita |
| 01006 |
Warning |
Privilégio não revogado |
| 01007 |
Warning |
Privilégio não concedido |
| 01S00 |
Warning |
Atributo de cadeia de conexão inválido |
| 01S01 |
Warning |
Erro na linha |
| 01S02 |
Warning |
Valor da opção alterado |
Classe 07 - Erro SQL Dinâmico
| SQLSTATE |
Exceção |
Descrição |
| 07001 |
ErrorProgrammingError |
Número errado de parâmetros |
| 07002 |
ErrorProgrammingError |
Campo COUNT incorreto |
| 07005 |
ErrorProgrammingError |
Instrução preparada, não uma especificação de cursor |
| 07006 |
ErrorProgrammingError |
Violação de atributo de tipo de dados restrito |
| 07009 |
ErrorProgrammingError |
Índice de descritores inválido |
| 07S01 |
ErrorProgrammingError |
Uso inválido do parâmetro padrão |
Classe 08 - Exceção de conexão
| SQLSTATE |
Exceção |
Descrição |
| 08001 |
ErrorOperacional |
O cliente não consegue estabelecer conexão |
| 08002 |
ErrorOperacional |
Nome da conexão em uso |
| 08003 |
ErrorOperacional |
Conexão não existe |
| 08004 |
ErrorOperacional |
O servidor rejeitou a conexão |
| 08007 |
ErrorOperacional |
Falha de conexão durante a transação |
| 08S01 |
ErrorOperacional |
Falha no link de comunicação |
Classe 21 - Violação de cardinalidade
| SQLSTATE |
Exceção |
Descrição |
| 21S01 |
ErrorProgrammingError |
A lista de valores de inserção não corresponde à lista de colunas |
| 21S02 |
ErrorProgrammingError |
O grau da tabela derivada não corresponde à lista de colunas |
Classe 22 - Exceção de dados
| SQLSTATE |
Exceção |
Descrição |
| 22001 |
DataError |
Dados de cadeia de caracteres, truncamento à direita |
| 22002 |
DataError |
Variável indicadora necessária, mas não fornecida |
| 22003 |
DataError |
Valor numérico fora do intervalo |
| 22007 |
DataError |
Formato de data e hora inválido |
| 22008 |
DataError |
Estouro de campo de data e hora |
| 22012 |
DataError |
Divisão por zero |
| 22015 |
DataError |
Estouro de campo de intervalo |
| 22018 |
DataError |
Valor de caractere inválido para especificação de conversão |
| 22019 |
DataError |
Caractere de escape inválido |
| 22025 |
DataError |
Sequência de escape inválida |
| 22026 |
DataError |
Incompatibilidade de comprimento de dados String |
Classe 23 - Violação de restrições de integridade
| SQLSTATE |
Exceção |
Descrição |
| 23000 |
ErrorIntegridadeErro |
Violação de restrições de integridade (geral) |
Classe 24 - Estado do cursor inválido
| SQLSTATE |
Exceção |
Descrição |
| 24000 |
Erro Interno |
Estado de cursor inválido |
Classe 25 - Estado inválido da transação
| SQLSTATE |
Exceção |
Descrição |
| 25000 |
ErrorOperacional |
Estado inválido da transação |
| 25S01 |
ErrorOperacional |
Estado da transação desconhecido |
| 25S02 |
ErrorOperacional |
A transação ainda está ativa |
| 25S03 |
ErrorOperacional |
A transação é revertida |
Classe 28 - Especificação de autorização inválida
| SQLSTATE |
Exceção |
Descrição |
| 28000 |
ErrorOperacional |
Especificação de autorização inválida (login falhado) |
Classe 34 - Nome do cursor inválido
| SQLSTATE |
Exceção |
Descrição |
| 34000 |
ErrorProgrammingError |
Nome de cursor inválido |
Classe 3C - Nome duplicado do cursor
| SQLSTATE |
Exceção |
Descrição |
| 3C000 |
ErrorProgrammingError |
Nome do cursor duplicado |
Classe 3D - Nome inválido do catálogo
| SQLSTATE |
Exceção |
Descrição |
| 3D000 |
ErrorProgrammingError |
Nome de catálogo inválido |
Classe 3F - Nome inválido do esquema
| SQLSTATE |
Exceção |
Descrição |
| 3F000 |
ErrorProgrammingError |
Nome de esquema inválido |
Classe 40 - Rollback de transações
| SQLSTATE |
Exceção |
Descrição |
| 40001 |
ErrorOperacional |
Falha de serialização (deadlock) |
| 40002 |
ErrorOperacional |
Violação de restrições de integridade causou rollback |
| 40003 |
ErrorOperacional |
Conclusão da instrução desconhecida |
Classe 42 - Erro de sintaxe ou violação da regra de acesso
| SQLSTATE |
Exceção |
Descrição |
| 42000 |
ErrorProgrammingError |
Erro de sintaxe ou violação de acesso |
| 42S01 |
ErrorProgrammingError |
A tabela base ou exibição já existe |
| 42S02 |
ErrorProgrammingError |
Tabela base ou exibição não encontrada |
| 42S11 |
ErrorProgrammingError |
O índice já existe |
| 42S12 |
ErrorProgrammingError |
Índice não encontrado |
| 42S21 |
ErrorProgrammingError |
A coluna já existe |
| 42S22 |
ErrorProgrammingError |
Coluna não encontrada |
Classe 44 - VIOLAÇÃO DA OPÇÃO DE VERIFICAÇÃO
| SQLSTATE |
Exceção |
Descrição |
| 44000 |
ErrorIntegridadeErro |
Violação COM OPÇÃO DE VERIFICAÇÃO |
Classe HY - condição específica de CLI
| SQLSTATE |
Exceção |
Descrição |
| HY000 |
DatabaseError |
Erro geral |
| HY001 |
ErrorOperacional |
Erro de alocação de memória |
| HY003 |
ErrorProgrammingError |
Tipo de buffer de aplicativo inválido |
| HY004 |
ErrorProgrammingError |
Tipo de dados SQL inválido |
| HY007 |
ErrorProgrammingError |
A declaração associada não está preparada |
| HY008 |
ErrorOperacional |
Operação cancelada |
| HY009 |
ErrorProgrammingError |
Uso inválido de ponteiro nulo |
| HY010 |
ErrorProgrammingError |
Erro de sequência de função |
| HY011 |
ErrorProgrammingError |
O atributo não pode ser definido agora |
| HY012 |
ErrorProgrammingError |
Código de operação de transação inválido |
| HY013 |
ErrorOperacional |
Erro de gerenciamento de memória |
| HY014 |
ErrorOperacional |
Limite de número de alças ultrapassado |
| HY015 |
ErrorProgrammingError |
Nenhum nome de cursor disponível |
| HY016 |
ErrorProgrammingError |
Não é possível modificar um descritor de linha de implementação |
| HY017 |
ErrorProgrammingError |
Uso inválido do handle de descritor alocado automaticamente |
| HY018 |
ErrorOperacional |
Servidor recusado pedido de cancelamento |
| HY019 |
ErrorProgrammingError |
Dados não caracteres e não binários enviados em partes |
| HY020 |
DataError |
Tentativa de concatenar um valor nulo |
| HY021 |
ErrorProgrammingError |
Informações de descritores inconsistentes |
| HY024 |
ErrorProgrammingError |
Valor de atributo inválido |
| HY090 |
ErrorProgrammingError |
Cadeia de caracteres ou comprimento de buffer inválido |
| HY091 |
ErrorProgrammingError |
Identificador de campo descritor inválido |
| HY092 |
ErrorProgrammingError |
Identificador de atributo/opção inválido |
| HY095 |
ErrorProgrammingError |
Tipo de função fora do alcance |
| HY096 |
ErrorProgrammingError |
Tipo de informação inválido |
| HY097 |
ErrorProgrammingError |
Tipo de coluna fora do alcance |
| HY098 |
ErrorProgrammingError |
Tipo de mira fora do alcance |
| HY099 |
ErrorProgrammingError |
Tipo anulável fora do alcance |
| HY100 |
ErrorProgrammingError |
Tipo de opção de exclusividade fora do intervalo |
| HY101 |
ErrorProgrammingError |
Tipo de opção de precisão fora do intervalo |
| HY103 |
ErrorProgrammingError |
Código de recuperação inválido |
| HY104 |
ErrorProgrammingError |
Precisão ou valor de escala inválido |
| HY105 |
ErrorProgrammingError |
Tipo de parâmetro inválido |
| HY106 |
ErrorProgrammingError |
Tipo de busca fora do alcance |
| HY107 |
ErrorProgrammingError |
Valor da linha fora do intervalo |
| HY109 |
ErrorProgrammingError |
Posição inválida do cursor |
| HY110 |
ErrorProgrammingError |
Conclusão inválida do driver |
| HY111 |
ErrorProgrammingError |
Valor inválido do marcador |
| HYC00 |
NotSupportedError |
Recurso opcional não implementado |
| HYT00 |
ErrorOperacional |
Tempo limite expirado |
| HYT01 |
ErrorOperacional |
O tempo limite da conexão expirou |
Classe IM - Erro do gerente do piloto
| SQLSTATE |
Exceção |
Descrição |
| IM001 |
InterfaceError |
O driver não suporta esta função |
| IM002 |
InterfaceError |
Nome da fonte de dados não encontrado |
| IM003 |
InterfaceError |
O driver especificado não pôde ser carregado |
| IM004 |
InterfaceError |
O SQLAllocHandle do driver no SQL_HANDLE_ENV falhou |
| IM005 |
InterfaceError |
O SQLAllocHandle do driver no SQL_HANDLE_DBC falhou |
| IM006 |
InterfaceError |
O SQLSetConnectAttr do driver falhou |
| IM007 |
InterfaceError |
Nenhuma fonte de dados ou driver especificados |
| IM008 |
InterfaceError |
Diálogo falhou |
| IM009 |
InterfaceError |
Não é possível carregar a DLL de tradução |
| IM010 |
InterfaceError |
Nome da fonte de dados muito longo |
| IM011 |
InterfaceError |
Nome do driver muito longo |
| IM012 |
InterfaceError |
Erro de sintaxe de palavra-chave DRIVER |
| IM014 |
InterfaceError |
DSN inválido |
| IM015 |
InterfaceError |
Fonte de dados corrompida de arquivo |
Números de erro comuns do SQL Server
Além do SQLSTATE, o SQL Server fornece números nativos de erro entre parênteses. Esses são os erros que você provavelmente encontrará no código da aplicação. Construa a lógica de retentativa em torno do erro 1205 (deadlock) e erros de conexão transitória (veja lógica de retentativa).
| Erro |
Padrão de mensagem |
Resolução |
| 208 |
Nome de objeto inválido |
Verifique se a tabela ou visualização existe e verifique a qualificação do esquema. |
| 547 |
Violação de restrição |
Uma restrição de chave estrangeira ou cheque falhou. |
| 2627 |
Violação única de restrição |
Um valor duplicado da chave foi inserido. |
| 2601 |
Violação de índice único |
Existe uma chave duplicada no índice. |
| 4060 |
Não é possível abrir banco de dados |
O banco de dados não existe ou o acesso é negado. |
| 18456 |
Falha no logon |
Falha de autenticação. Verifique credenciais. |
| 1205 |
Vítima de deadlock |
A transação foi revertida. Repita a operação. |
Referência rápida de sintoma para exceção
Use esta tabela para mapear os sintomas comuns ao tipo de exceção que você deve identificar:
| Sintoma |
Exceção |
Causa provável |
| "Login falhado para o usuário" |
OperationalError |
Credenciais erradas ou usuário não mapeado no banco de dados. |
| "Cliente incapaz de estabelecer conexão" |
OperationalError |
Servidor inacessível, firewall ou problema de DNS. |
| "Tempo expirou" |
OperationalError |
Tempo limite de consulta ou conexão. Aumente o tempo de espera ou otimize a consulta. |
| "Nome do objeto inválido" |
ProgrammingError |
Tabela não existe ou esquema não especificado. |
| "Sintaxe incorreta" |
ProgrammingError |
Erro de sintaxe SQL. Consulta de teste no SSMS. |
| "Número errado de parâmetros" |
ProgrammingError |
A contagem de parâmetros não corresponde aos marcadores de lugar. |
| "Violação da CHAVE PRIMÁRIA" |
IntegrityError |
Chave duplicada. Use MERGE ou verifique antes de inserir. |
| "Violação de CHAVE ESTRANGEIRA" |
IntegrityError |
A linha referenciada não existe. Insira o pai primeiro. |
| "Transação travada" |
OperationalError (erro 1205) |
Contenção de trava. Implementar lógica de repetição. |
| "Dados de string ou binários seriam truncados" |
DataError |
O valor excede o comprimento da coluna. Verifique dados ou aumente o tamanho da coluna. |
| "Conversão falhada" |
DataError |
Incompatibilidade de tipos. Use o tipo correto de Python para a coluna. |
| "Palavra-chave desconhecida" |
ConnectionStringParseError |
Erro de digitação na palavra-chave da cadeia de conexão. |
| "Callproc não é suportado" |
NotSupportedError |
Use cursor.execute("EXECUTE ...") em seu lugar. |
Práticas recomendadas
-
Observe exceções específicas antes das genéricas. Ordem de mais específico (
IntegrityError) para menor específico (Error).
-
Sempre manuseie o IntegrityError para operações de modificação de dados. Violações de restrições são esperadas em operação normal (por exemplo, um usuário tentando criar um nome de usuário duplicado).
-
Registre o contexto completo do erro para a solução de problemas. A exceção expõe
driver_error (texto estável, derivado do SQLSTATE) e ddbc_error (mensagem do lado do servidor). Registre ambos; classificar em driver_error.
-
Implemente lógica de retentativa para erros transitórios (falhas de conexão, deadlocks). Veja lógica de Retentar.
-
Use rollback() em manipuladores de exceções para limpar transações que falham. Sem um rollback explícito, a conexão permanece em estado de transação falhada.
Conteúdo relacionado