Tratamento de erros e códigos SQLSTATE para mssql-python

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.