Устранение неполадок mssql-django

Диагностируйте и устраняйте распространённые проблемы с серверной частью mssql-django для SQL Server, База данных SQL Azure, Управляемый экземпляр SQL Azure и базы данных SQL в среде Microsoft Fabric.

Проблемы с подключением

В этом разделе рассматриваются наиболее распространенные ошибки подключения и способы их устранения.

Драйвер ODBC не найден

Симптомы

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

Или:

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

Возможные причины и решения:

  • Драйвер ODBC не установлен

    Установите драйвер ODBC Microsoft для SQL Server. Ссылки на скачивание см. в разделе "Скачать драйвер ODBC для SQL Server".

  • Установлены несколько версий драйверов

    Укажите точное имя драйвера или путь в 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",
            },
        },
    }
    

    В Linux укажите полный путь:

    "OPTIONS": {
        "driver": "/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.6.1",
    },
    
  • Проверка установленных драйверов

    • В Linux или macOS выполните команду odbcinst -q -d.
    • В Windows проверьте источники данных ODBC в средствах администрирования.

В подключении отказано

Симптомы

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

Возможные причины и решения:

  • Tcp/IP не включен в SQL Server

    • Откройте диспетчер конфигурации SQL Server.
    • В разделе SQL Server конфигурации сети включите TCP/IP.
    • В свойствах TCP/IP активируйте IP-адрес, используемый для подключения.
    • Перезапустите службу SQL Server.
  • Брандмауэр блокирует порт 1433

    • Убедитесь, что правила брандмауэра разрешают входящие подключения через порт 1433.
    • Для Azure SQL добавьте IP-адрес клиента в параметры брандмауэра портала Azure.
  • Неправильное имя сервера или порт

    Проверьте значения HOST и PORT в своей конфигурации.

Сбой входа

Симптомы

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

Возможные причины и решения:

  • Неверные учетные данные

    Проверьте имя пользователя и пароль.

  • Пользователь не существует

    Убедитесь, что имя входа сопоставляется с пользователем в целевой базе данных.

  • SQL Server аутентификация отключена

    Включите проверку подлинности в смешанном режиме или используйте Windows или Microsoft Entra аутентификацию.

Время соединения истекло

Симптомы

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

Возможные причины и решения:

  • Задержка сети

    Увеличьте connection_timeout в разделе OPTIONS.

  • Перегруженный сервер

    Увеличьте connection_retries и connection_retry_backoff_time.

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

Проблемы с миграцией

Эти ошибки возникают во время операций миграции Django с SQL Server.

Проблемы с датой и временем

Now() значения смещаются, когда USE_TZ=True

Симптомы

Метки времени, записанные с помощью Django Now(), auto_now или auto_now_add, смещаются, когда часовой пояс узла SQL Server не UTC.

Решение. Обновление до mssql-django версии 1.7.2 или более поздней версии. Версия 1.7.2 исправляет генерацию SQL с учетом часовых поясов Now() и обработку смещения datetimeoffset.

AttributeError при вызове .explain()

Симптомы

AttributeError: ... explain_format ...

Решение. Обновление до mssql-django версии 1.7.2 или более поздней версии. Версия 1.7.2 исправляет проблему совместимости компилятора для Django 4.0 и более поздних версий, а также метаданные explain.

Не удается изменить автофилд

Симптомы

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

Решение: SQL Server не поддерживает изменение типа поля с или на AutoField. Создайте модель с нужным типом поля, перенесите данные вручную, а затем удалите старую таблицу. Обходные пути см. в разделе "Миграция баз данных" с помощью mssql-django.

Не удается переименовать из-за ограничения внешнего ключа

Симптомы

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

Решение: SQL Server требует удаления ограничений внешнего ключа перед переименованием столбцов. Используйте SeparateDatabaseAndState при миграции. Пример см. в разделе "Миграция баз данных с помощью mssql-django".

Проблемы с кодировкой

Ошибки кодирования обычно возникают при pyodbc неправильном определении символьных данных из SQL Server.

Ошибки кодировки Юникода

Симптомы

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

Решение. Настройка pyodbc кодирования в словаре OPTIONS :

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

Проблемы с FreeTDS

Для FreeTDS требуется определенная конфигурация, которая отличается от драйвера ODBC Microsoft.

ошибка host_is_server

Симптомы

Сбой подключения при использовании FreeTDS без указания host_is_server.

Решение. Задайте значение host_is_serverTrue при использовании FreeTDS:

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

Дополнительные сведения о конфигурации FreeTDS см. в разделе "Параметры подключения" для mssql-django.

Проблемы с тестовой базой данных

Создание и уничтожение тестовой базы данных могут завершаться ошибкой в зависимости от метода аутентификации.

Не удается создать тестовую базу данных с управляемой идентификацией

Симптомы

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

Или:

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

Средство запуска тестов не может создать или удалить тестовую базу данных при использовании проверки подлинности с помощью ActiveDirectoryMsi (управляемого удостоверения). Это ограничение существует, так как:

  • Учетные данные управляемой идентичности получаются из среды размещения (например, виртуальной машины Azure и Azure App Service).

  • Средство запуска тестов пытается подключиться с использованием учетных данных базы данных test на этапе teardown.

  • Управляемой идентичности можно назначить роли на уровне базы данных, но для создания и удаления тестовых баз данных обычно требуются разрешения на уровне сервера, которых у средств запуска тестов часто нет.

Затронутые методы проверки подлинности:

  • ActiveDirectoryMsi (управляемое удостоверение Azure)
  • ActiveDirectoryServicePrincipal (только если настроено на уровне сервера)

Поддерживаемые методы проверки подлинности (работает создание тестовой базы данных):

  • ActiveDirectoryPassword
  • ActiveDirectoryIntegrated
  • Проверка подлинности SQL (имя пользователя и пароль)

Компромиссы проверки подлинности для тестовых сред

Метод Без секрета Работает с автоматическим созданием/удалением тестовой базы данных Типичное использование
ActiveDirectoryMsi Yes Обычно нет (если права на уровне сервера не предоставлены) продуктивные рабочие нагрузки, размещённые в Azure
ActiveDirectoryServicePrincipal Нет (секрет клиента или сертификат) Зависит от предоставленных прав на уровне сервера CI/CD с явным управлением идентификацией
ActiveDirectoryPassword нет Да (с достаточными разрешениями SQL) Среды разработки и контролируемые среды CI
Проверка подлинности SQL нет Да (с достаточными разрешениями SQL) Локальные или изолированные тестовые среды

Решения:

  • Для разработки: используйте --keepdb флаг для пропуска сноса тестовой базы данных:

    python manage.py test --keepdb
    
  • Для конвейеров CI/CD: заранее создайте выделенную тестовую базу данных и предоставьте управляемой идентификации разрешения CREATE TABLE и 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];
    
  • Альтернатива: используйте аутентификацию SQL для тестовых сред или переключитесь на ActiveDirectoryPassword для тестовых раннеров CI/CD.

Процедуры отката

Если миграция прерывается до завершения, используйте эту последовательность отката, чтобы вернуться к заведомо работоспособному состоянию:

  1. Остановите запись приложения, чтобы избежать дополнительного смещения схемы.

  2. Проверка состояния миграции:

    python manage.py showmigrations
    python manage.py sqlmigrate <app_label> <migration_number>
    
  3. Откат к последней известной хорошей миграции:

    python manage.py migrate <app_label> <previous_migration>
    
  4. Если схема и история миграций расходятся, осторожно исправляйте состояние с помощью --fake только после проверки фактической схемы базы данных.

  5. Сначала повторно запустите миграцию в промежуточной среде, а затем повторите попытку в рабочей среде.

Important

Для разрушительных миграций, таких как удаление, переименование и изменение типов столбцов, перед развертыванием выполните тестовую резервную копию. Если откат с помощью миграции невозможен, восстановите систему из резервной копии и повторно примените проверенные миграции.

Проблемы с Docker и контейнерами

Для образов контейнеров требуется явная установка драйвера ODBC и зависимостей сборки.

Драйвер ODBC не найден в контейнере

Симптомы

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

Возможные причины и решения:

  • Драйвер ODBC не установлен в образе контейнера

    Базовые образы Slim и Alpine не включают драйвер ODBC. Добавьте репозиторий Microsoft APT и установите msodbcsql18 в Dockerfile. Полный пример Dockerfile см. в статье "Развертывание в службе приложений ".

  • Отсутствующий unixodbc-dev пакет

    Пакет pyodbc компонуется с libodbc.so. Установите unixodbc-dev (Debian/Ubuntu) или unixODBC-devel (RHEL/Fedora) перед установкой пакетов Python.

pyodbc не может построить на тонких изображениях

Симптомы

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

Или:

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

Решение: Установите зависимости для сборки перед pip install:

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

Кроме того, используйте многоэтапную сборку, чтобы сохранить окончательный образ небольшим:

# 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/*

Контейнер не может подключиться к SQL Server

Симптомы

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

Возможные причины и решения:

  • Имя службы Docker Compose не используется в качестве узла

    При использовании Docker Compose задайте DB_HOST имя службы (например, db), а не localhost127.0.0.1.

  • контейнер SQL Server не готов

    Для запуска контейнера SQL Server требуется несколько секунд. Добавьте проверку работоспособности или задержку запуска:

    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
    
  • Конфликты сопоставления портов

    Если на узле запущен другой экземпляр SQL Server, измените предоставленный порт (например, 1434:1433) и обновите конфигурацию Django соответствующим образом.

Azure SQL временное восстановление ошибок

Компонент mssql-django серверной части автоматически обнаруживает подключения к База данных SQL Azure и Управляемый экземпляр SQL Azure путем выполнения запроса к SERVERPROPERTY('EngineEdition'). При работе с Azure SQL серверная часть повторяет попытки подключения при возникновении временных сбоев (например, временных ограничений ресурсов или кратковременных перебоев в сети).

Это поведение можно настроить с помощью параметров connection_retries и connection_retry_backoff_time:

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

Эти параметры применяются только к первоначальному созданию подключений. Серверная часть не повторяет неудачные запросы. Если после установления соединения запрос завершается из-за временной ошибки, исключение передаётся в код приложения. Используйте логику повторных попыток на уровне приложения (например, django-retry-db или настраиваемое ПО промежуточного слоя) для обеспечения устойчивости на уровне запросов.

Медленные запросы и регрессии планов

Эти проблемы обычно требуют анализа на стороне сервера вместе с проверкой запросов на уровне Django.

Запрос работает медленнее или начинает завершаться по тайм-ауту

Симптомы

Тот же QuerySet со временем начинает работать медленнее или начинает завершаться по тайм-ауту после развертывания, изменения индекса или обновления статистики.

Возможные причины и решения:

  • Начните со встроенных отчетов о производительности

    Для SQL Server и Управляемый экземпляр SQL Azure откройте панель мониторинга производительности в SQL Server Management Studio. Для База данных SQL Azure откройте аналитические сведения о производительности запросов для База данных SQL Azure. Обычно эти средства являются лучшей отправной точкой, чем разовые запросы DMV, поскольку они позволяют быстро выявить ресурсоёмкие запросы, ожидания и нехватку ресурсов.

  • Регрессия планирования

    Используйте хранилище запросов для поиска медленного запроса и проверки наличия нескольких планов. Начните с представлений «Запросы с регрессией» и «Запросы с наибольшим потреблением ресурсов», описанных в рекомендациях по мониторингу рабочих нагрузок с помощью хранилище запросов.

  • Неэффективный план выполнения

    Откройте фактический план выполнения для инструкции и проверьте наличие сканирований таблиц или индексов, затратных операций поиска по ключу, переполнений хэша или неточных оценок строк. Общие сведения см. в разделе "План выполнения".

  • Неправильно определённое узкое место

    Если запрос не привязан к ЦП, используйте статистику ожидания хранилище запросов и определите узкие места для различения ЦП, памяти, операций ввода-вывода диска, блокировки и давления подключения.

  • Исправление, примененное в неправильном слое

    Примените наименьшее эффективное исправление: добавьте или измените индексы, обновите статистику, уменьшите выбранные столбцы и строки или пакетную большую запись. Если требуется экстренная мера по смягчению последствий, DBA может временно принудительно применить в хранилище запросов заведомо корректный план, пока вы устраняете первопричину.

Использование dbshell для интерактивных запросов

Команда управления Django dbshell открывает интерактивную оболочку SQL, подключенную к базе данных:

python manage.py dbshell

Серверная часть использует sqlcmd при настройке драйвера Microsoft ODBC или isql при использовании FreeTDS. Убедитесь, что инструмент доступен через PATH:

  • Windows: sqlcmd входит в состав средств SQL Server, или его можно скачать отдельно.
  • Linux и macOS: установка mssql-tools18 из репозитория Microsoft.