Rozwiązywanie problemów z mssql-django

Diagnozowanie i rozwiązywanie typowych problemów z zapleczem mssql-django dla SQL Server, Azure SQL Database, Azure SQL Managed Instance i bazy danych SQL w Microsoft Fabric.

mssql-django 2.0 obsługuje domyślną ścieżkę sterownika pyodbc oraz opcjonalną ścieżkę sterownika mssql-python. Więcej informacji można znaleźć w artykule Wybierz sterownik bazy danych dla mssql-django.

Problemy z połączeniem

W tej sekcji opisano najczęstsze błędy połączeń i sposoby ich rozwiązywania.

Nie znaleziono sterownika ODBC w ścieżce pyodbc

Objawy:

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

Or:

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

Możliwe przyczyny i rozwiązania:

  • Sterownik ODBC nie został zainstalowany

    Zainstaluj sterownik Microsoft ODBC dla SQL Server, gdy używasz domyślnej ścieżki pyodbc. Aby uzyskać linki do pobierania, zobacz Pobieranie sterownika ODBC dla SQL Server. Ścieżka mssql-python nie używa zewnętrznego sterownika ODBC.

  • Zainstalowano wiele wersji sterowników

    Określ dokładną nazwę sterownika lub ścieżkę w pliku settings.py:

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

    W systemie Linux określ pełną ścieżkę:

    "OPTIONS": {
        "driver": "/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.6.1",
    },
    
  • Sprawdzanie zainstalowanych sterowników

    • W systemie Linux/macOS uruchom polecenie odbcinst -q -d.
    • Na Windows sprawdź źródła danych ODBC w narzędziach administracyjnych.

mssql-python odrzuca opcję połączenia

Objawy:

Alias ustawiający "python_driver": "mssql_python" kończy się niepowodzeniem podczas ustanawiania połączenia po przeniesieniu słów kluczowych ciągu połączenia pyodbc do OPTIONS["extra_params"], z jednym z poniższych komunikatów o błędzie:

mssql_python.exceptions.ConnectionStringParseError: Connection string parsing failed:
  Unknown keyword 'longasmax' is not recognized
mssql_python.exceptions.ConnectionStringParseError: Connection string parsing failed:
  Reserved keyword 'driver' is controlled by the driver and cannot be specified by the user

Nazwa słowa kluczowego w wiadomości jest pisana małymi literami, więc słowo, które napisałeś jako LongAsMax , wygląda jako longasmax. ConnectionStringParseError nie jest częścią hierarchii wyjątków DB-API, więc Django nie opakowuje go jako django.db.utils błąd.

Możliwe przyczyny i rozwiązania:

  • Słowo kluczowe tylko dla pyodbc w extra_params

    Ścieżka dostępu mssql-python sprawdza poprawność extra_params względem listy dozwolonych elementów. DRIVER i APP są zarezerwowane dla kierowcy i tworzą formularz Reserved keyword. DSN, SERVERNAME, MARS_Connection oraz słowa kluczowe dostępne wyłącznie w pyodbc, takie jak LongAsMax, ColumnEncryption, AnsiNPW, WSID, QuotedId, Regional, UseFMTONLY, Current Language, Description, Network Library oraz Connect Timeout, nie znajdują się na liście dozwolonych elementów i powodują wygenerowanie postaci Unknown keyword. Usuń słowo kluczowe lub użyj domyślnej ścieżki pyodbc dla aliasu, który wymaga tej opcji ODBC.

  • Opcja sterownika przeznaczona do sterowania mssql-python

    Ścieżka mssql-python ignoruje driver, dsn, host_is_server, oraz unicode_results. HOST i PORT stają się SERVER=<server>,<port>, a puste HOST staje się localhost.

Zależność mssql-python jest już za stara

Objawy:

Alias ustawiający "python_driver": "mssql_python" kończy się niepowodzeniem podczas ustanawiania połączenia z jednym z poniższych błędów:

django.core.exceptions.ImproperlyConfigured: mssql-python 1.15.0 or newer is required; you have 1.14.0
django.core.exceptions.ImproperlyConfigured: The 'python_driver' connection option requests mssql-python, but the module could not be imported: No module named 'mssql_python'. Install it with 'pip install "mssql-python>=1.15.0"'.

Druga forma oznacza, że mssql_python moduł w ogóle nie da się importować.

Rozwiązanie: Instalacja mssql-python>=1.15.0. mssql-django 2.0 deklaruje mssql-python>=1.15.0, więc standardowe pip install mssql-django powoduje wybranie zgodnej wersji na obsługiwanych platformach.

Mechanizm awaryjny sterownika 17 nie ma zastosowania do mssql-python

Objawy:

Alias ustawiony "python_driver": "mssql_python" nadal nie działa, mimo że Microsoft ODBC Driver 17 dla SQL Server jest zainstalowany.

W tej sprawie nie ma wyraźnego błędu. Ścieżka dostępu mssql-python po cichu ignoruje opcję driver, więc nawiązanie połączenia kończy się niepowodzeniem z odpowiednim błędem warstwy bazowej. Jeśli zamiast tego przeniesiesz nazwę sterownika do extra_params, pojawi się błąd Reserved keyword 'driver'. Zobacz mssql-python odrzuca opcję połączenia.

Rozwiązanie: Użyj domyślnej ścieżki pyodbc, jeśli alias musi używać zewnętrznego sterownika ODBC Driver 17. Ścieżka mssql-python nie wraca do sterownika 17 i ignoruje driver tę opcję. Ta ścieżka nie wymaga osobno zainstalowanego sterownika ODBC.

Odmowa połączenia

Objawy:

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

Możliwe przyczyny i rozwiązania:

  • Protokół TCP/IP nie jest włączony w SQL Server

    • Otwórz SQL Server Configuration Manager.
    • W obszarze SQL Server Konfiguracja sieci włącz protokół TCP/IP.
    • W obszarze Właściwości protokołu TCP/IP aktywuj adres IP używany na potrzeby połączenia.
    • Uruchom ponownie usługę SQL Server.
  • Zapora blokująca port 1433

    • Sprawdź, czy reguły zapory zezwalają na połączenia przychodzące na porcie 1433.
    • W przypadku Azure SQL dodaj adres IP klienta w ustawieniach zapory portalu Azure.
  • Nieprawidłowa nazwa serwera lub port

    Sprawdź wartości HOST i PORT w konfiguracji.

Logowanie nie powiodło się

Objawy:

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

Na ścieżce mssql-python:

django.db.utils.OperationalError: Driver Error: Invalid authorization specification; DDBC Error: [Microsoft][SQL Server]Login failed for user '<user_id>'.

Możliwe przyczyny i rozwiązania:

  • Nieprawidłowe poświadczenia

    Sprawdź nazwę użytkownika i hasło.

  • Baza danych w NAME nie istnieje

    Na SQL Server ścieżka mssql-python wyświetla ten sam OperationalError komunikat co złe hasło, więc sam komunikat nie mówi, które hasło trafiłeś. Potwierdź, że baza danych istnieje, zanim zmienisz dane uwierzytelniające. Skieruj NAME na master, aby przetestować samo logowanie: jeśli połączenie zostanie nawiązane, dane logowania są poprawne, a problem dotyczy bazy danych. Ścieżka pyodbc zgłasza ten przypadek osobno jako Cannot open database "<database>" requested by the login. The login failed. (4060).

    Azure SQL Database relacjonuje ten przypadek inaczej. Ścieżka w mssql-python zgłasza Driver Error: General error; DDBC Error: [Microsoft][SQL Server]Cannot open server "<server>" requested by the login. The login failed. W komunikacie podano nazwę serwera, ale nazwa serwera jest poprawna. Sprawdź NAME zamiast tego.

  • Użytkownik nie istnieje

    Potwierdź, że login jest mapowany do użytkownika w docelowej bazie danych.

  • SQL Server uwierzytelnianie wyłączone

    Włącz uwierzytelnianie w trybie mieszanym lub użyj uwierzytelniania Windows lub Microsoft Entra.

Przekroczenie limitu czasu połączenia

Objawy:

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

Możliwe przyczyny i rozwiązania:

  • Opóźnienie sieci

    Zwiększ connection_timeout w OPCJACH.

  • Azure SQL Database w modelu bezserwerowym z włączonym automatycznym wstrzymywaniem

    Automatycznie wstrzymana baza danych wznawia się przy pierwszej próbie połączenia, która może zakończyć się błędem 40613, podczas gdy baza danych wznawia działanie. Ustaw connection_timeout na co najmniej 60 i ponów pierwsze połączenie. Więcej informacji można znaleźć w Azure SQL Database serverless oraz Automatyczne wstrzymywanie i automatyczne wznawianie.

  • Serwer przeciążony

    Zwiększ connection_retries i connection_retry_backoff_time.

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

Problemy z migracją

Te błędy występują podczas operacji migracji Django względem SQL Server.

Problemy z RAW SQL i GROUP BY

Błędy te występują, gdy nieprzetworzone lub adnotowane zapytania z klauzulą GROUP BY przechodzą przez etap przepisywania symboli zastępczych po stronie backendu.

IndexError dla GROUP BY ze znakami ucieczki %% i rzeczywistymi parametrami

Objawy:

IndexError: Replacement index N out of range for positional args tuple

Zapytanie działa bez klauzuli GROUP BY i bez literalu ucieczkowego %% , ale nie udaje się, gdy oba są obecne wraz z rzeczywistym parametrem %s .

Rozwiązanie: Aktualizacja do aktualnej mssql-django wersji. Backend zawęża wyrażenie regularne przepisujące placeholdery wyłącznie do %% i %s, więc literały %% ze znakiem ucieczki są zachowywane dosłownie i nie są wstrzykiwane żadne widmowe placeholdery.

NotImplementedError dla IntegerChoices w surowych zapytaniach GROUP BY

Objawy:

NotImplementedError: Not supported type <enum '...'> (StatusChoices.IN_PROGRESS)

Ta sama wartość typu enum działa w zapytaniach ORM oraz w surowych zapytaniach bez GROUP BY, ale kończy się błędem, gdy jest przekazywana jako parametr do surowego zapytania zawierającego klauzulę GROUP BY.

Rozwiązanie: Aktualizacja do aktualnej mssql-django wersji. Backend używa isinstance do sprawdzania typów parametrów w ścieżce GROUP BY, więc IntegerChoices (podklasa int) jest poprawnie wiązane. bool nadal wiąże bit, a zwykłe int pozostaje bez zmian.

Problemy z wyszukiwaniem Regex

__regex lub __iregex nie zwraca wierszy

Objawy: Zapytanie działa bez błędu i zwraca pusty zbiór wyników, mimo że wiersze odpowiadają wzorcowi.

Product.objects.filter(name__regex=r"^Widget \d+$")  # no rows, though "Widget 42" exists

Przyczyna: dbo.REGEXP_LIKE ignoruje dosłownie białe odstępy w wzorze. Wzór jest dopasowany tak, jakby był ^Widget\d+$, czego żadna wartość zawierająca spację nie może spełnić. Nic się nie podnosi, więc pusty wynik wygląda jak problem z danymi.

Rozwiązanie: Zapisz odstęp jako escape lub klasę znaku:

Product.objects.filter(name__regex=r"^Widget\s\d+$")
Product.objects.filter(name__regex=r"^Widget[ ]\d+$")

Cannot find ... dbo.REGEXP_LIKE

Objawy:

django.db.utils.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Cannot find either column "dbo" or the user-defined function or aggregate "dbo.REGEXP_LIKE", or the name is ambiguous. (4121) (SQLExecDirectW)')

Na ścieżce mssql-python :

django.db.utils.ProgrammingError: Driver Error: Syntax error or access violation; DDBC Error: [Microsoft][SQL Server]Cannot find either column "dbo" or the user-defined function or aggregate "dbo.REGEXP_LIKE", or the name is ambiguous.

Przyczyna: Zestaw CLR nie jest zainstalowany w bazie danych, którą przeszukujesz. Jest instalowany oddzielnie dla każdej bazy danych, a nie dla każdego serwera.

Rozwiązanie: Uruchom python manage.py install_regex_clr <database> dla tej bazy danych. Uruchom go ponownie po usunięciu i ponownym utworzeniu bazy danych. Zobacz Ustaw wyszukiwania regex.

Problemy z datą i godziną

Now() wartości ulegają przesunięciu, gdy USE_TZ=True

Objawy:

Znaczniki czasu zapisane za pomocą Django Now(), auto_now lub auto_now_add ulegają przesunięciu, gdy strefa czasowa hosta SQL Server nie jest ustawiona na UTC.

Rozwiązanie: Aktualizacja do aktualnej mssql-django wersji. Backend generuje kod SQL świadomy stref czasowych Now(), zachowuje offsety datetimeoffset oraz odczytuje dane o strefach czasowych za pośrednictwem zoneinfo i tzdata.

AttributeError podczas wywoływania .explain()

Objawy:

AttributeError: ... explain_format ...

Rozwiązanie: Aktualizacja do aktualnej mssql-django wersji. Backend obsługuje metadane EXPLAIN dla każdej obsługiwanej wersji Django.

Nie można zmienić AutoField

Objawy:

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

Rozwiązanie: SQL Server nie obsługuje zmiany pola z lub na AutoField. Utwórz nowy model z żądanym typem pola, przeprowadź migrację danych ręcznie, a następnie upuść starą tabelę. Aby uzyskać obejścia, zobacz Database migrations with mssql-django (Migracje baz danych za pomocą narzędzia mssql-django).

Zmiana nazwy nie powodzi się z powodu ograniczenia klucza obcego

Objawy:

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

Rozwiązanie: SQL Server wymaga porzucania ograniczeń klucza obcego przed zmianą nazwy kolumn. Użyj SeparateDatabaseAndState podczas migracji. Przykład można znaleźć w temacie Database migrations with mssql-django (Migracje bazy danych za pomocą narzędzia mssql-django).

Problemy z kodowaniem

Błędy kodowania zazwyczaj występują na ścieżce pyodbc, gdy pyodbc błędnie interpretuje dane znaków z SQL Server.

Błędy kodowania Unicode

Objawy:

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

Rozwiązanie: Skonfiguruj kodowanie pyodbc w słowniku OPTIONS. Ścieżka mssql-python ignoruje unicode_results.

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

Problemy z usługą FreeTDS

FreeTDS wymaga konfiguracji specyficznej dla pyodbc, która różni się od sterownika Microsoft ODBC.

błąd host_is_server

Objawy:

Połączenie kończy się niepowodzeniem w przypadku korzystania z usługi FreeTDS bez określenia wartości host_is_server.

Rozwiązanie: ustaw dla host_is_server wartość True, jeśli używasz FreeTDS:

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

Aby uzyskać więcej informacji na temat konfiguracji usługi FreeTDS, zobacz Opcje połączenia dla mssql-django.

Testowanie problemów z bazą danych

Testowanie tworzenia i zniszczenia bazy danych może zakończyć się niepowodzeniem w zależności od metody uwierzytelniania.

Nie można utworzyć testowej bazy danych z tożsamością zarządzaną

Objawy:

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

Or:

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

Moduł uruchamiający testy nie może utworzyć ani usunąć testowej bazy danych podczas korzystania z uwierzytelniania ActiveDirectoryMsi (tożsamość zarządzana). To ograniczenie istnieje, ponieważ:

  • Poświadczenia zarządzanej tożsamości są uzyskiwane ze środowiska hosta (takiego jak maszyna wirtualna platformy Azure i usługa App Service).

  • Program uruchamiający testy próbuje nawiązać połączenie przy użyciu poświadczeń bazy danych test podczas etapu teardown.

  • Tożsamości zarządzanej można przypisać role na poziomie bazy danych, ale tworzenie i usuwanie testowej bazy danych zwykle wymaga uprawnień na poziomie serwera, których narzędzia uruchamiające testy często nie mają.

Metody uwierzytelniania, których dotyczy problem:

  • ActiveDirectoryMsi (tożsamość zarządzana platformy Azure)
  • ActiveDirectoryServicePrincipal (tylko w przypadku skonfigurowania na poziomie serwera)

Obsługiwane metody uwierzytelniania (działa tworzenie testowej bazy danych):

  • ActiveDirectoryPassword
  • ActiveDirectoryIntegrated
  • Uwierzytelnianie SQL (nazwa użytkownika/hasło)

Kompromisy uwierzytelniania dla środowisk testowych

Metoda bez użycia sekretów Działa z automatycznym tworzeniem/usuwaniem testowej bazy danych. Typowe użycie
ActiveDirectoryMsi Yes Zwykle nie (chyba że udzielono praw na poziomie serwera) obciążenia produkcyjne hostowane Azure
ActiveDirectoryServicePrincipal Nie (klucz tajny klienta ani certyfikat) Zależy od udzielonych praw na poziomie serwera CI/CD z jawnie zdefiniowanym zarządzaniem tożsamością
ActiveDirectoryPassword Nie. Tak (z wystarczającymi uprawnieniami SQL) Środowiska deweloperskie i kontrolowane środowiska CI
Uwierzytelnianie SQL Nie. Tak (z wystarczającymi uprawnieniami SQL) Środowiska testowe lokalne lub izolowane

Rozwiązania:

  • W przypadku programowania: użyj --keepdb flagi, aby pominąć testowanie usuwania bazy danych:

    python manage.py test --keepdb
    
  • Dla potoków CI/CD: utwórz wcześniej dedykowaną bazę danych do testów i nadaj zarządzanej tożsamości CREATE TABLE i ALTER następujące uprawnienia:

    -- 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];
    
  • Alternatywnie: użyj uwierzytelniania SQL w środowiskach testowych lub przełącz się na ActiveDirectoryPassword dla runnerów testów CI/CD.

Procedury cofania zmian

Gdy migracja nie powiedzie się w trakcie, użyj tej sekwencji wycofywania zmian, aby powrócić do znanego, poprawnego stanu:

  1. Wstrzymaj operacje zapisu aplikacji, aby uniknąć dodatkowego dryfu schematu.

  2. Sprawdź stan migracji:

    python manage.py showmigrations
    python manage.py sqlmigrate <app_label> <migration_number>
    
  3. Wróć do ostatniej znanej dobrej migracji:

    python manage.py migrate <app_label> <previous_migration>
    
  4. Jeśli schemat i historia migracji są rozbieżne, stan należy ostrożnie naprawić za pomocą --fake dopiero po zweryfikowaniu rzeczywistego schematu bazy danych.

  5. Najpierw ponownie uruchom migracje w środowisku testowym, a następnie spróbuj ponownie w środowisku produkcyjnym.

Ważna

W przypadku destruktywnych migracji, takich jak usuwanie, zmienianie nazwy i zmiany typu kolumny, przed wdrożeniem należy wykonać przetestowaną kopię zapasową. Jeśli wycofanie zmian za pomocą migracji nie jest możliwe, przywróć system z kopii zapasowej i ponownie zastosuj zweryfikowane migracje.

Problemy z platformą Docker i kontenerem

Obrazy kontenerów wymagają wyraźnej instalacji sterownika ODBC i budowania zależności przy użyciu domyślnej ścieżki pyodbc. Wariant mssql-python nie wymaga oddzielnej instalacji sterownika ODBC, ale nadal potrzebuje środowiska wykonawczego unixODBC, ponieważ backend importuje pyodbc podczas ładowania Django.

Nie można odnaleźć sterownika ODBC w kontenerze

Objawy:

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

Możliwe przyczyny i rozwiązania:

  • Sterownik ODBC nie został zainstalowany w obrazie kontenera

    Obrazy bazowe Slim lub Alpine nie zawierają sterownika ODBC. Dodaj repozytorium APT firmy Microsoft i zainstaluj msodbcsql18 w pliku Dockerfile, jeśli używasz pyodbc. Pełny przykład pliku Dockerfile znajduje się w sekcji Wdrażanie w usłudze App Service.

  • Brak unixodbc-dev pakietu

    Koło pyodbc łączy się z elementem libodbc.so. Zainstaluj unixodbc-dev (Debian/Ubuntu) lub unixODBC-devel (RHEL/Fedora) przed zainstalowaniem pakietów Python.

  • apt-get autoremove usunięte libgssapi-krb5-2 po zainstalowaniu sterownika

    msodbcsql18 ładuje libgssapi-krb5-2 w czasie wykonywania bez deklarowania go jako zależności. Biblioteka zwykle jest instalowana jako zależność elementu curl, więc usunięcie curl za pomocą --auto-remove lub uruchomienie następnie apt-get autoremove spowoduje jej usunięcie. Obraz buduje się bez błędów, po czym wszystkie połączenia zawodzą. Instaluj libgssapi-krb5-2 wprost i nie usuwaj automatycznie po instalacji sterownika.

Zgłoszono brak sterownika 17 podczas instalacji wersji 18

Objawy:

Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 17 for SQL Server' : file not found (0) (SQLDriverConnect)")

W komunikacie o błędzie podano wersję 17, ale odbcinst -q -d pokazuje, że wersja 18 jest zarejestrowana, a dpkg -l msodbcsql18 — że jest zainstalowana.

Przyczyna: Zarejestrowana jest wersja 18, ale nie ładuje się, więc mssql-django wraca do wersji 17, która nie jest zainstalowana. Mechanizm awaryjny zgłasza sterownik, który był próbowany jako drugi, a nie ten, który nie zadziałał.

Rozwiązanie: Instalacja libgssapi-krb5-2 i odbudowa. Zobacz poprzednią uwagę dotyczącą automatycznego usuwania, aby dowiedzieć się, jak dochodzi do zniknięcia biblioteki.

Błąd ładowania modułu pyodbc w kontenerze

Objawy:

django.core.exceptions.ImproperlyConfigured: Error loading pyodbc module: libodbc.so.2: cannot open shared object file: No such file or directory

Przyczyna: Obraz nie zawiera środowiska uruchomieniowego unixODBC. mssql-django importuje pyodbc podczas ładowania backendu, więc ten błąd pojawia się także na ścieżce mssql-python, zanim zostanie podjęta jakakolwiek próba połączenia.

Rozwiązanie: Install unixodbc (lub unixodbc-dev).

Sterownik mssql-python nie załadowuje się

Objawy:

django.db.utils.OperationalError: Driver Error: Connection operation failed; DDBC Error: Failed to load the driver.

Przyczyna: Sterownik dostarczany z mssql-python wymaga bibliotek środowiska uruchomieniowego Kerberos, których nie zawierają odchudzone obrazy bazowe.

Rozwiązanie: Zainstalować libkrb5-3 i libgssapi-krb5-2.

pyodbc nie kompiluje się na minimalnych obrazach

Objawy:

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

Or:

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

Rozwiązanie: Zainstaluj zależności kompilacji przed :pip install

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

Alternatywnie użyj kompilacji wieloetapowej, aby zachować mały obraz końcowy:

# 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 libgssapi-krb5-2 \
    && apt-get purge -y curl gnupg2 \
    && rm -rf /var/lib/apt/lists/*
COPY --from=builder /wheels /wheels
RUN pip install --no-cache-dir /wheels/*

Kontener nie może nawiązać połączenia z SQL Server

Objawy:

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

Możliwe przyczyny i rozwiązania:

  • Nazwa usługi Docker Compose nie jest używana jako host

    W przypadku korzystania z narzędzia Docker Compose ustaw DB_HOST na nazwę usługi (na przykład db), a nie localhost ani 127.0.0.1.

  • kontener SQL Server nie jest gotowy

    Uruchomienie kontenera SQL Server zajmuje kilka sekund. Dodaj kontrolę kondycji lub opóźnienie uruchamiania:

    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
    
  • Konflikty mapowania portów

    Jeśli na hoście jest uruchomione inne wystąpienie SQL Server, zmień uwidoczniony port (na przykład 1434:1433) i odpowiednio zaktualizuj konfigurację Django.

Azure SQL — odzyskiwanie po błędach przejściowych

Backend mssql-django automatycznie wykrywa połączenia z usługami Azure SQL Database i Azure SQL Managed Instance, odpytując SERVERPROPERTY('EngineEdition'). Podczas pracy z usługą Azure SQL zaplecze ponawia próby nawiązania połączenia w razie błędów przejściowych (takich jak tymczasowe ograniczenia zasobów lub krótkotrwałe przerwy w sieci).

To zachowanie można dostroić za pomocą opcji connection_retries i connection_retry_backoff_time OPTIONS:

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

Te ustawienia dotyczą tylko początkowego ustanowienia połączenia. Zaplecze nie ponawia próby nieudanych zapytań. Jeśli po nawiązaniu połączenia zapytanie zakończy się niepowodzeniem z powodu błędu przejściowego, wyjątek zostanie przekazany do kodu aplikacji. Użyj logiki ponawiania na poziomie aplikacji (na przykład django-retry-db lub niestandardowego oprogramowania pośredniczącego) w celu uzyskania odporności na poziomie zapytania.

Powolne zapytania i regresje planu

Te problemy zwykle wymagają analizy po stronie serwera wraz z przeglądem zapytań na poziomie Django.

Zapytanie jest wolniejsze lub zaczyna przekraczać limit czasu

Objawy:

Ten sam zestaw zapytań staje się wolniejszy w czasie lub zaczyna przekraczać limit czasu po wdrożeniu, zmianie indeksu lub aktualizacji statystyk.

Możliwe przyczyny i rozwiązania:

  • Rozpoczynanie pracy z wbudowanymi raportami wydajności

    W przypadku programu SQL Server i usługi Azure SQL Managed Instance otwórz w SQL Server Management Studio element Panel wydajności. W przypadku Azure SQL Database otwórz narzędzie Szczegółowe informacje o wydajności zapytań dla Azure SQL Database. Te narzędzia są zwykle lepszym pierwszym krokiem niż zapytania DMV ad hoc, ponieważ szybko uwidoczniają kosztowne zapytania, oczekiwania i ciśnienie zasobów.

  • Regresja planu

    Użyj Query Store, aby znaleźć powolne zapytanie i sprawdzić, czy ma wiele planów wykonania. Zacznij od widoków Zapytania z regresją i Zapytania zużywające najwięcej zasobów opisanych w artykule Najlepsze praktyki monitorowania obciążeń przy użyciu Query Store.

  • Nieefektywny plan wykonania

    Otwórz rzeczywisty plan wykonania dla instrukcji i sprawdź, czy nie ma skanów tabeli lub indeksu, dużych odnośników kluczy, rozlewów skrótów lub niedokładnych szacunków wierszy. Aby zapoznać się z omówieniem planu wykonywania, zobacz Omówienie planu wykonywania.

  • Zidentyfikowano niewłaściwe wąskie gardło

    Jeśli zapytanie nie jest ograniczane przez procesor, użyj statystyk oczekiwań w Query Store i identyfikowania wąskich gardeł, aby rozróżnić problemy z procesorem, pamięcią, operacjami we/wy dysku, blokowaniem i presją połączeń.

  • Poprawka zastosowana w niewłaściwej warstwie

    Zastosuj najmniejszą skuteczną zmianę: dodaj lub dostosuj indeksy, zaktualizuj statystyki, ogranicz liczbę wybranych kolumn i wierszy lub wykonuj duże operacje zapisu partiami. Jeśli potrzebujesz doraźnych działań naprawczych, administrator bazy danych może tymczasowo wymusić sprawdzony plan w Query Store, podczas gdy usuwasz przyczynę źródłową.

Używanie programu dbshell dla zapytań interakcyjnych

Polecenie zarządzania Django dbshell otwiera interaktywną powłokę SQL połączoną z bazą danych:

python manage.py dbshell

Zaplecze używa sqlcmd, gdy konfigurujesz sterownik Microsoft ODBC, lub isql, gdy używasz FreeTDS. Sprawdź, czy narzędzie jest w zmiennej PATH:

  • Windows: sqlcmd wchodzi w skład narzędzi programu SQL Server, lub można go pobrać osobno.
  • Linux i macOS: zainstaluj z mssql-tools18 repozytorium Microsoft.