Solucionar problemas de mssql-django

Diagnostique e resolva problemas comuns no mssql-django back-end do SQL Server, do Banco de Dados SQL do Azure, da Instância Gerenciada de SQL do Azure e do Banco de Dados SQL no Microsoft Fabric.

Problemas de conexão

Esta seção aborda os erros de conexão mais comuns e como resolvê-los.

Driver ODBC não encontrado

Sintomas:

django.core.exceptions.ImproperlyConfigured: 'ODBC Driver 18 for SQL Server' is not a recognized ODBC driver

Ou:

Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 18 for SQL Server'")

Possíveis causas e soluções:

  • Driver ODBC não instalado

    Instale o driver ODBC Microsoft para SQL Server. Para obter links de download, consulte Baixar o Driver ODBC para SQL Server.

  • Várias versões do driver instaladas

    Especifique o nome ou caminho exato do driver em settings.py:

    DATABASES = {
        "default": {
            "ENGINE": "mssql",
            "NAME": "<your-database>",
            "USER": "<your-username>",
            "PASSWORD": "<your-password>",
            "HOST": "<your-server>",
            "PORT": "1433",
            "OPTIONS": {
                "driver": "ODBC Driver 17 for SQL Server",
            },
        },
    }
    

    No Linux, especifique o caminho completo:

    "OPTIONS": {
        "driver": "/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.6.1",
    },
    
  • Verificar drivers instalados

    • No Linux/macOS, execute odbcinst -q -d.
    • Em Windows, verifique as fontes de dados ODBC nas Ferramentas Administrativas.

Conexão recusada

Sintomas:

django.db.utils.OperationalError: ('08001', '[08001] ... TCP Provider: Error code 0x2749 ...')

Possíveis causas e soluções:

  • TCP/IP não habilitado no SQL Server

    • Abra o SQL Server Configuration Manager.
    • Em SQL Server Configuração de Rede, habilite TCP/IP.
    • Em Propriedades TCP/IP, ative o endereço IP usado para a conexão.
    • Reinicie o serviço SQL Server.
  • Firewall bloqueando a porta 1433

    • Verifique se as regras de firewall permitem conexões de entrada na porta 1433.
    • Para SQL do Azure, adicione o IP do cliente nas configurações de firewall do portal Azure.
  • Nome ou porta do servidor incorreto

    Verifique os valores HOST e PORT em sua configuração.

Falha no logon

Sintomas:

django.db.utils.OperationalError: ('28000', "[28000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user '<username>'.")

Possíveis causas e soluções:

  • Credenciais incorretas

    Verifique o nome de usuário e a senha.

  • O usuário não existe

    Confirme se o logon foi mapeado para um usuário no banco de dados de destino.

  • SQL Server autenticação desabilitada

    Habilite a autenticação de modo misto ou use a autenticação do Windows ou a autenticação do Microsoft Entra.

Tempo de espera da conexão esgotado

Sintomas:

django.db.utils.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 18 for SQL Server]Login timeout expired')

Possíveis causas e soluções:

  • Latência da rede

    Aumentar connection_timeout em OPÇÕES.

  • Servidor sobrecarregado

    Aumentar connection_retries e connection_retry_backoff_time.

    "OPTIONS": {
        "driver": "ODBC Driver 18 for SQL Server",
        "connection_timeout": 30,
        "connection_retries": 5,
        "connection_retry_backoff_time": 10,
    },
    

Problemas de migração

Esses erros ocorrem durante as operações de migração do Django em relação a SQL Server.

Problemas de data e hora

Now() os valores são deslocados quando USE_TZ=True

Sintomas:

Carimbos de data e hora gravados com Django Now(), auto_now ou auto_now_add ficam deslocados quando o fuso horário do host do SQL Server não está em UTC.

Solução: atualize para mssql-django 1.7.2 ou posterior. A versão 1.7.2 corrige a geração de SQL com reconhecimento Now() de fuso horário e o tratamento de deslocamento de datetimeoffset .

AttributeError ao chamar .explain()

Sintomas:

AttributeError: ... explain_format ...

Solução: atualize para mssql-django 1.7.2 ou posterior. A versão 1.7.2 corrige a compatibilidade do compilador para o Django 4.0 e, posteriormente, explica os metadados.

Não é possível alterar o AutoField

Sintomas:

django.db.utils.ProgrammingError: Cannot alter column to or from an IDENTITY column

Solução: SQL Server não dá suporte à alteração de um campo de ou para AutoField. Crie um novo modelo com o tipo de campo desejado, migre os dados manualmente e solte a tabela antiga. Para obter soluções alternativas, consulte migrações de banco de dados com mssql-django.

Falha ao renomear com restrição de chave estrangeira

Sintomas:

django.db.utils.ProgrammingError: ... could not drop constraint ...

Solução: SQL Server requer a remoção de restrições de chave estrangeira antes de renomear colunas. Use SeparateDatabaseAndState em sua migração. Para obter um exemplo, consulte migrações de banco de dados com mssql-django.

Problemas de codificação

Erros de codificação normalmente ocorrem quando pyodbc interpreta mal os dados de caractere de SQL Server.

Erros de codificação Unicode

Sintomas:

UnicodeDecodeError: 'utf-8' codec can't decode byte ...

Solução: Configurar a codificação pyodbc no dicionário OPTIONS:

"OPTIONS": {
    "driver": "ODBC Driver 18 for SQL Server",
    "unicode_results": True,
},

Problemas de FreeTDS

O FreeTDS requer uma configuração específica que difere do driver ODBC Microsoft.

host_is_server erro

Sintomas:

A conexão falha ao usar o FreeTDS sem especificar host_is_server.

Solução: defina host_is_server para True quando você usar o FreeTDS:

"OPTIONS": {
    "driver": "FreeTDS",
    "host_is_server": True,
},

Para obter mais informações sobre a configuração do FreeTDS, consulte as opções de conexão para mssql-django.

Testar problemas de banco de dados

A criação e a destruição do banco de dados de teste podem falhar dependendo do método de autenticação.

Não é possível criar um banco de dados de teste com identidade gerenciada

Sintomas:

django.db.utils.DatabaseError: ('42000', '[42000] ... EXECUTE permission denied on object ...')

Ou:

django.db.utils.OperationalError: ('28000', ... login failed ...)

O executor de testes falha ao criar ou destruir o banco de dados de teste ao usar a autenticação ActiveDirectoryMsi (identidade gerenciada). Essa limitação existe porque:

  • As credenciais de identidade gerenciada são obtidas do ambiente do host (como Azure VM e Serviço de Aplicativo).

  • O executor de testes tenta se conectar usando as credenciais do banco de dados test durante a desmontagem.

  • A identidade gerenciada pode receber funções no nível do banco de dados, mas a criação e a exclusão do banco de dados de teste geralmente exigem permissões no nível do servidor que os executores de teste geralmente não têm.

Métodos de autenticação afetados:

  • ActiveDirectoryMsi (identidade gerenciada do Azure)
  • ActiveDirectoryServicePrincipal (quando configurado somente no escopo do servidor)

Métodos de autenticação com suporte (a criação do banco de dados de teste funciona):

  • ActiveDirectoryPassword
  • ActiveDirectoryIntegrated
  • Autenticação sql (nome de usuário/senha)

Compensações de autenticação para ambientes de teste

Método Sem segredo Funciona com a criação/exclusão automática do banco de dados de teste Uso típico
ActiveDirectoryMsi Yes Geralmente não (a menos que os direitos no nível do servidor sejam concedidos) cargas de trabalho de produção hospedadas no Azure
ActiveDirectoryServicePrincipal Não (segredo/certificado do cliente) Depende dos direitos concedidos no nível do servidor CI/CD com gerenciamento de identidade explícito
ActiveDirectoryPassword Não Sim (com permissões sql suficientes) Ambientes de desenvolvimento e de CI controlados
Autenticação do SQL Não Sim (com permissões sql suficientes) Ambientes de teste locais ou isolados

Soluções:

  • Para desenvolvimento: Use --keepdb o sinalizador para ignorar a desmontagem do banco de dados de teste:

    python manage.py test --keepdb
    
  • Para pipelines de CI/CD: crie previamente um banco de dados de teste dedicado e conceda permissões à identidade gerenciada CREATE TABLE e ALTER:

    -- Connect as a server admin, then:
    USE [test_database_name];
    
    -- Grant permissions for managed identity (replace with your identity name)
    CREATE USER [your-app-identity] FROM EXTERNAL PROVIDER;
    GRANT CREATE TABLE TO [your-app-identity];
    GRANT ALTER ON SCHEMA::dbo TO [your-app-identity];
    
  • Alternativa: Use a autenticação SQL para ambientes de teste ou mude para ActiveDirectoryPassword nos executores de teste de CI/CD.

Procedimentos de reversão

Quando uma migração falhar no meio do caminho, use esta sequência de reversão para retornar a um bom estado conhecido:

  1. Interrompa as operações de gravação do aplicativo para evitar divergência adicional de esquema.

  2. Inspecione o estado de migração:

    python manage.py showmigrations
    python manage.py sqlmigrate <app_label> <migration_number>
    
  3. Reverta para a última boa migração conhecida:

    python manage.py migrate <app_label> <previous_migration>
    
  4. Se o esquema e o histórico de migração divergirem, repare o estado com cuidado usando --fake somente depois de verificar o esquema real do banco de dados.

  5. Execute novamente as migrações em um ambiente de preparo primeiro e tente novamente a produção.

Importante

Para migrações destrutivas, como remover, renomear e alterar o tipo de coluna, faça um backup testado antes da implantação. Se a reversão via migração não for possível, restaure a partir do backup e reaplique as migrações validadas.

Problemas de docker e contêiner

As imagens de contêiner exigem a instalação explícita do driver ODBC e dependências de compilação.

Driver ODBC não encontrado no contêiner

Sintomas:

Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 18 for SQL Server'")

Possíveis causas e soluções:

  • Driver ODBC não instalado na imagem do contêiner

    As imagens base Slim ou Alpine não incluem o driver ODBC. Adicione o repositório APT Microsoft e instale msodbcsql18 no Dockerfile. Consulte Implantar no Serviço de Aplicativo para obter um exemplo completo do Dockerfile.

  • Pacote ausente unixodbc-dev

    O pacote wheel pyodbc é vinculado a libodbc.so. Instale unixodbc-dev (Debian/Ubuntu) ou unixODBC-devel (RHEL/Fedora) antes de instalar Python pacotes.

pyodbc falha ao criar em imagens finas

Sintomas:

error: command 'gcc' failed: No such file or directory

Ou:

fatal error: sql.h: No such file or directory

Solução: Instale as dependências de compilação antes de pip install:

RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc \
    g++ \
    unixodbc-dev

Como alternativa, use um build de vários estágios para manter a imagem final pequena:

# Build stage
FROM python:3.12-slim AS builder
RUN apt-get update && apt-get install -y --no-install-recommends gcc g++ unixodbc-dev
COPY requirements.txt .
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt

# Runtime stage
FROM python:3.12-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl gnupg2 unixodbc \
    && curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg \
    && curl -fsSL https://packages.microsoft.com/config/debian/12/prod.list > /etc/apt/sources.list.d/mssql-release.list \
    && apt-get update \
    && ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 \
    && apt-get purge -y --auto-remove curl gnupg2 \
    && rm -rf /var/lib/apt/lists/*
COPY --from=builder /wheels /wheels
RUN pip install --no-cache-dir /wheels/*

O contêiner não pode se conectar ao SQL Server

Sintomas:

django.db.utils.OperationalError: ('08001', '... TCP Provider: Error code 0x2749 ...')

Possíveis causas e soluções:

  • Nome do serviço do Docker Compose não é usado como host

    Ao usar o Docker Compose, defina DB_HOST como o nome do serviço (por exemplo, db), não localhost ou 127.0.0.1.

  • SQL Server contêiner não está pronto

    O contêiner SQL Server leva vários segundos para ser iniciado. Adicionar uma verificação de saúde ou um atraso na inicialização:

    services:
      db:
        image: mcr.microsoft.com/mssql/server:2022-latest
        healthcheck:
          test: /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$$MSSQL_SA_PASSWORD" -No -Q "SELECT 1" || exit 1
          # $$ escapes the $ sign in Docker Compose YAML
          interval: 10s
          retries: 10
          start_period: 10s
      web:
        depends_on:
          db:
            condition: service_healthy
    
  • Conflitos de mapeamento de porta

    Se outra instância do SQL Server estiver em execução no host, altere a porta exposta (por exemplo1434:1433) e atualize a configuração do Django adequadamente.

Recuperação de erros transitórios do SQL do Azure

O mssql-django back-end detecta automaticamente as conexões com o Banco de Dados SQL do Azure e a Instância Gerenciada de SQL do Azure consultando SERVERPROPERTY('EngineEdition'). Ao executar em SQL do Azure, o back-end tenta novamente conexões em erros transitórios (como limites de recursos temporários ou breves interrupções de rede).

Você pode ajustar esse comportamento com as opções connection_retries e connection_retry_backoff_time:

"OPTIONS": {
    "driver": "ODBC Driver 18 for SQL Server",
    "connection_retries": 5,
    "connection_retry_backoff_time": 5,
},

Essas configurações se aplicam somente ao estabelecimento de conexão inicial. O back-end não tenta novamente consultas com falha. Se uma consulta falhar com um erro transitório após a conexão ser estabelecida, a exceção será propagada para o código do aplicativo. Use a lógica de repetição no nível do aplicativo (por exemplo, django-retry-db ou um middleware personalizado) para resiliência no nível de consulta.

Consultas lentas e regressões de plano

Esses problemas geralmente precisam de análise do lado do servidor junto com a revisão de consulta no nível do Django.

A consulta fica lenta ou começa a expirar por tempo limite

Sintomas:

O mesmo conjunto de consultas fica mais lento ao longo do tempo ou passa a expirar por tempo limite após uma implantação, uma alteração de índice ou uma atualização de estatísticas.

Possíveis causas e soluções:

  • Começar com relatórios de desempenho internos

    Para SQL Server e Instância Gerenciada de SQL do Azure, abra o Painel de Desempenho no SQL Server Management Studio. No Banco de Dados SQL do Azure, abra Análise de desempenho de consultas para Banco de Dados SQL do Azure. Essas ferramentas geralmente são uma etapa inicial melhor do que consultas ad hoc nas DMVs, porque identificam rapidamente consultas de alto custo, esperas e pressão de recursos.

  • Regressão de plano

    Use Repositório de Consultas para identificar a consulta lenta e verificar se há vários planos para ela. Comece pelas exibições Regressed Queries e Top Resource Consuming Queries descritas em Práticas recomendadas para monitorar cargas de trabalho com o Repositório de Consultas.

  • Plano de execução ineficiente

    Abra um plano de execução real para o comando e verifique se há varreduras de tabela ou de índice, operações extensas de pesquisa de chave, derramamentos de hash ou estimativas imprecisas de linhas. Para obter informações em segundo plano, consulte a visão geral do plano de execução.

  • Gargalo incorreto identificado

    Se a consulta não estiver limitada pela CPU, use as estatísticas de espera do Repositório de Consultas e Identificar gargalos para distinguir entre CPU, memória, E/S de disco, bloqueio e pressão nas conexões.

  • Correção aplicada na camada errada

    Aplique a menor correção eficaz: adicione ou ajuste índices, atualize estatísticas, reduza o número de colunas e linhas selecionadas ou divida gravações grandes em lotes. Se você precisar de uma mitigação de emergência, um DBA poderá forçar temporariamente um plano conhecido como bom no Repositório de Consultas enquanto você corrige a causa raiz.

Usar o dbshell para consultas interativas

O comando de gerenciamento do dbshell Django abre um shell SQL interativo conectado ao banco de dados:

python manage.py dbshell

O back-end usa sqlcmd quando você configura o driver ODBC Microsoft ou isql quando usa o FreeTDS. Verifique se a ferramenta está em seu PATH:

  • Windows: sqlcmd está incluído nas ferramentas do SQL Server, ou você pode baixá-lo separadamente.
  • Linux e macOS: instale mssql-tools18 no repositório Microsoft.