Fehlerbehebung für mssql-django

Diagnostizieren und Beheben häufiger Probleme mit dem mssql-django Back-End für SQL Server, Azure SQL-Datenbank, Azure SQL Managed Instance und SQL-Datenbank in Microsoft Fabric.

Verbindungsprobleme

In diesem Abschnitt werden die am häufigsten auftretenden Verbindungsfehler und deren Behebung behandelt.

ODBC-Treiber nicht gefunden

Symptome:

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

Oder:

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

Mögliche Ursachen und Lösungen:

  • ODBC-Treiber nicht installiert

    Installieren Sie den Microsoft ODBC-Treiber für SQL Server. Downloadlinks finden Sie unter "ODBC-Treiber herunterladen" für SQL Server.

  • Mehrere Treiberversionen installiert

    Geben Sie den genauen Treibernamen oder Pfad in 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",
            },
        },
    }
    

    Geben Sie unter Linux den vollständigen Pfad an:

    "OPTIONS": {
        "driver": "/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.6.1",
    },
    
  • Überprüfen der installierten Treiber

    • Führen Sie unter Linux/macOS odbcinst -q -d aus.
    • Überprüfen Sie auf Windows ODBC-Datenquellen in den Verwaltungstools.

Verbindung verweigert

Symptome:

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

Mögliche Ursachen und Lösungen:

  • TCP/IP ist für SQL Server nicht aktiviert

    • Öffnen Sie den SQL Server-Konfigurations-Manager.
    • Aktivieren Sie unter SQL Server NetzwerkkonfigurationTCP/IP.
    • Aktivieren Sie in den TCP/IP-Eigenschaften die für die Verbindung verwendete IP-Adresse.
    • Starten Sie den SQL Server-Dienst neu.
  • Firewall blockiert Port 1433

    • Überprüfen Sie, ob Firewallregeln eingehende Verbindungen an Port 1433 zulassen.
    • Fügen Sie für Azure SQL Ihre Client-IP in den Azure Portalfirewalleinstellungen hinzu.
  • Falscher Servername oder -port

    Überprüfen Sie die Werte HOST und PORT in Ihrer Konfiguration.

Fehler bei der Anmeldung

Symptome:

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

Mögliche Ursachen und Lösungen:

  • Falsche Anmeldeinformationen

    Überprüfen Sie den Benutzernamen und das Kennwort.

  • Der Benutzer ist nicht vorhanden.

    Vergewissern Sie sich, dass die Anmeldung einem Benutzer in der Zieldatenbank zugeordnet ist.

  • SQL Server Authentifizierung deaktiviert

    Aktivieren Sie die Authentifizierung im gemischten Modus, oder verwenden Sie Windows oder Microsoft Entra Authentifizierung.

Verbindungstimeout

Symptome:

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

Mögliche Ursachen und Lösungen:

  • Netzwerklatenz

    Erhöhen Sie connection_timeout in OPTIONEN.

  • Serverüberladung

    Erhöhen Sie connection_retries und connection_retry_backoff_time.

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

Migrationsprobleme

Diese Fehler treten bei Django-Migrationsvorgängen gegen SQL Server auf.

Probleme mit Datum und Uhrzeit

Now() Werte werden verschoben, wenn USE_TZ=True

Symptome:

Zeitstempel, die mit Django Now(), auto_now oder auto_now_add geschrieben werden, sind verschoben, wenn die Zeitzone des SQL-Server-Hosts nicht UTC ist.

Lösung: Upgrade auf mssql-django 1.7.2 oder höher. Version 1.7.2 behebt die zeitzonenbewusste Now()SQL-Generierung und die Offsetbehandlung von datetimeoffset.

AttributeError beim Anrufen .explain()

Symptome:

AttributeError: ... explain_format ...

Lösung: Upgrade auf mssql-django 1.7.2 oder höher. Version 1.7.2 behebt die Kompatibilität des Compilers für Django 4.0 und höher und erläutert Metadaten.

AutoField kann nicht geändert werden

Symptome:

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

Lösung: SQL Server unterstützt keine Änderung eines Felds von oder zu .AutoField Erstellen Sie ein neues Modell mit dem gewünschten Feldtyp, migrieren Sie die Daten manuell, und legen Sie dann die alte Tabelle ab. Problemumgehungen finden Sie unter Datenbankmigrationen mit mssql-django.

Umbenennen schlägt aufgrund einer Fremdschlüsselbeschränkung fehl

Symptome:

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

Lösung: SQL Server erfordert das Ablegen von Fremdschlüsseleinschränkungen vor dem Umbenennen von Spalten. Verwenden Sie SeparateDatabaseAndState in Ihrer Migration. Ein Beispiel finden Sie unter Datenbankmigrationen mit mssql-django.

Codierungsprobleme

Codierungsfehler treten in der Regel auf, wenn pyodbc Zeichendaten aus SQL Server falsch interpretiert werden.

Unicode-Codierungsfehler

Symptome:

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

Lösung: Konfigurieren der pyodbc Codierung im OPTIONS Wörterbuch:

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

FreeTDS-Probleme

FreeTDS erfordert eine bestimmte Konfiguration, die sich vom Microsoft ODBC-Treiber unterscheidet.

host_is_server Fehler

Symptome:

Verbindung schlägt fehl, wenn FreeTDS ohne Angabe host_is_serververwendet wird.

Lösung: Legen Sie host_is_server auf True fest, wenn Sie FreeTDS verwenden:

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

Weitere Informationen zur FreeTDS-Konfiguration finden Sie unter "Verbindungsoptionen für mssql-django".

Testen von Datenbankproblemen

Die Erstellung und Zerstörung der Testdatenbank kann je nach Authentifizierungsmethode fehlschlagen.

Die Testdatenbank mit verwalteter Identität kann nicht erstellt werden.

Symptome:

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

Oder:

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

Der Testläufer kann die Testdatenbank nicht erstellen oder löschen, wenn Sie die ActiveDirectoryMsi-Authentifizierung mit verwalteter Identität verwenden. Diese Einschränkung besteht aus folgenden Gründen:

  • Anmeldeinformationen für verwaltete Identitäten werden aus der Hostumgebung abgerufen (z. B. Azure VM und App Service).

  • Der Testläufer versucht, sich beim Teardown mit den Datenbank-Anmeldeinformationen von test zu verbinden.

  • Einer verwalteten Identität können Rollen auf Datenbankebene zugewiesen werden, aber zum Erstellen und Löschen von Testdatenbanken sind in der Regel Berechtigungen auf Serverebene erforderlich, über die Test-Runner häufig nicht verfügen.

Betroffene Authentifizierungsmethoden:

  • ActiveDirectoryMsi (von Azure verwaltete Identität)
  • ActiveDirectoryServicePrincipal (nur bei Konfiguration auf Serverebene)

Unterstützte Authentifizierungsmethoden (Testdatenbankerstellung funktioniert):

  • ActiveDirectoryPassword
  • ActiveDirectoryIntegrated
  • SQL-Authentifizierung (Benutzername/Kennwort)

Kompromisse bei der Authentifizierung für Testumgebungen

Methode Geheimnislos Funktioniert mit automatischem Erstellen/Löschen von Test-DBs Typische Nutzung
ActiveDirectoryMsi Yes In der Regel nein (es sei denn, Rechte auf Serverebene werden gewährt) In Azure gehostete Produktionsworkloads
ActiveDirectoryServicePrincipal Nein (geheimer Clientschlüssel/Zertifikat) Hängt von den gewährten Rechten auf Serverebene ab CI/CD mit expliziter Identitätsverwaltung
ActiveDirectoryPassword No Ja (mit ausreichenden SQL-Berechtigungen) Entwickler- und kontrollierte CI-Umgebungen
SQL-Authentifizierung No Ja (mit ausreichenden SQL-Berechtigungen) Lokale oder isolierte Testumgebungen

Lösungen:

  • Für die Entwicklung: Verwenden Sie das Flag --keepdb, um die Bereinigung der Testdatenbank zu überspringen:

    python manage.py test --keepdb
    
  • Für CI/CD-Pipelines: Erstellen Sie eine dedizierte Testdatenbank vorab und gewähren Sie die verwaltete Identität CREATE TABLE und ALTER Berechtigungen:

    -- 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];
    
  • Alternative: Verwenden Sie die SQL-Authentifizierung für Testumgebungen, oder wechseln Sie für CI/CD-Testläufer zu ActiveDirectoryPassword.

Rollback-Prozeduren

Wenn eine Migration während des Vorgangs fehlschlägt, verwenden Sie diese Rollback-Sequenz, um zu einem bekanntermaßen funktionsfähigen Zustand zurückzukehren:

  1. Beenden Sie Anwendungsschreibvorgänge, um zusätzliche Schemaabweichungen zu vermeiden.

  2. Überprüfen des Migrationsstatus:

    python manage.py showmigrations
    python manage.py sqlmigrate <app_label> <migration_number>
    
  3. Führen Sie einen Rollback auf die letzte bekannte gute Migration durch:

    python manage.py migrate <app_label> <previous_migration>
    
  4. Wenn das Schema und die Migrationshistorie voneinander abweichen, korrigieren Sie den Zustand sorgfältig mit --fake, aber erst, nachdem Sie das tatsächliche Datenbankschema überprüft haben.

  5. Führen Sie Migrationen zuerst in einer Staging-Umgebung erneut aus und versuchen Sie es dann in der Produktionsumgebung erneut.

Important

Erstellen Sie vor der Bereitstellung ein getestetes Backup für destruktive Migrationen wie Löschen, Umbenennungen und Änderungen des Spaltentyps. Wenn ein Rollback mittels Migration nicht möglich ist, stellen Sie das System aus einer Sicherung wieder her und wenden Sie die validierten Migrationen erneut an.

Probleme mit Docker und Containern

Container-Images erfordern die explizite Installation von ODBC-Treibern und Build-Abhängigkeiten.

ODBC-Treiber im Container nicht gefunden

Symptome:

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

Mögliche Ursachen und Lösungen:

  • ODBC-Treiber nicht im Containerimage installiert

    Schlanke oder Alpine-Basis-Images enthalten den ODBC-Treiber nicht. Fügen Sie das Microsoft-APT-Repository hinzu und installieren Sie msodbcsql18 in Ihrem Dockerfile. Ein vollständiges Dockerfile-Beispiel finden Sie unter Deploy to App Service.

  • Fehlendes unixodbc-dev Paket

    Das pyodbc Rad verbindet sich mit libodbc.so. Installieren Sie unixodbc-dev (Debian/Ubuntu) oder unixODBC-devel (RHEL/Fedora), bevor Sie Python Pakete installieren.

Pyodbc baut nicht auf schlanken Bildern auf

Symptome:

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

Oder:

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

Lösung: Installieren Sie die Build-Abhängigkeiten vor pip install:

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

Alternativ können Sie einen mehrstufigen Build verwenden, um das endgültige Image klein zu halten:

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

Container kann keine Verbindung mit SQL Server herstellen

Symptome:

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

Mögliche Ursachen und Lösungen:

  • Docker Compose-Dienstname nicht als Host verwendet

    Wenn Sie Docker Compose verwenden, legen Sie DB_HOST den Dienstnamen fest (z. B db. ), nicht localhost oder 127.0.0.1.

  • SQL Server Container nicht bereit

    Der SQL Server-Container benötigt mehrere Sekunden zum Starten. Zustandsprüfung oder Startverzögerung hinzufügen:

    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
    
  • Portzuordnungskonflikte

    Wenn eine andere Instanz von SQL Server auf dem Host ausgeführt wird, ändern Sie den verfügbar gemachten Port (z. B1434:1433. ) und aktualisieren Sie die Django-Konfiguration entsprechend.

Azure SQL vorübergehende Fehlerwiederherstellung

Das mssql-django Back-End erkennt automatisch Azure SQL-Datenbank und Azure SQL Managed Instance Verbindungen durch AbfragenSERVERPROPERTY('EngineEdition'). Beim Betrieb mit Azure SQL versucht das Back-End bei vorübergehenden Fehlern (z. B. vorübergehenden Ressourcenbeschränkungen oder kurzzeitigen Netzwerkunterbrechungen) erneut, eine Verbindung herzustellen.

Sie können dieses Verhalten mit den connection_retriesOptionenconnection_retry_backoff_time anpassen:

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

Diese Einstellungen gelten nur für die anfängliche Verbindungseinrichtung. Das Backend versucht fehlgeschlagene Abfragen nicht erneut. Wenn eine Abfrage nach dem Herstellen der Verbindung mit einem vorübergehenden Fehler fehlschlägt, wird die Ausnahme an den Anwendungscode weitergegeben. Verwenden Sie die Wiederholungslogik auf Anwendungsebene (z. B. django-retry-db oder eine benutzerdefinierte Middleware) für die Resilienz auf Abfrageebene.

Langsame Abfragen und Planen von Regressionen

Diese Probleme erfordern in der Regel eine serverseitige Analyse sowie eine Überprüfung der Abfragen auf Django-Ebene.

Die Abfrage wird langsamer oder es kommt zu Zeitüberschreitungen.

Symptome:

Dieselbe Abfrage wird im Laufe der Zeit langsamer oder verursacht nach einer Bereitstellung, einer Indexänderung oder einer Aktualisierung von Statistiken Zeitüberschreitungen.

Mögliche Ursachen und Lösungen:

  • Beginnen Mit integrierten Leistungsberichten

    Öffnen Sie für SQL Server und Azure SQL Managed Instance das Performance Dashboard in SQL Server Management Studio. Öffnen Sie für Azure SQL-Datenbank Abfrageleistungsanalyse für Azure SQL-Datenbank. Diese Werkzeuge sind in der Regel ein besserer erster Schritt als Ad-hoc-DMV-Abfragen, da sie teure Abfragen, Wartezeiten und Ressourcenengpässe schnell sichtbar machen.

  • Planen der Regression

    Verwenden Sie Abfragespeicher, um die langsame Abfrage zu finden und zu überprüfen, ob sie über mehrere Pläne verfügt. Beginnen Sie mit den Ansichten "Regressed Queries" und "Top Resource Consuming Queries", die in bewährten Methoden für die Überwachung von Workloads mit Abfragespeicher beschrieben werden.

  • Ineffizienter Ausführungsplan

    Öffnen Sie einen tatsächlichen Ausführungsplan für die Anweisung, und suchen Sie nach Tabellen- oder Indexüberprüfungen, großen Schlüsselsuchen, Hash-Überläufen oder ungenauen Zeilenschätzungen. Hintergrundinformationen finden Sie unter Übersicht über den Ausführungsplan.

  • Falscher Engpass identifiziert

    Wenn die Abfrage nicht CPU-gebunden ist, verwenden Sie Abfragespeicher Wartestatistik, und identifizieren Sie Engpässe, um CPU, Arbeitsspeicher, Datenträger-E/A, Blockierung und Verbindungsdruck zu unterscheiden.

  • Korrektur auf der falschen Ebene angewendet

    Wenden Sie den kleinsten effektiven Fix an: Indizes hinzufügen oder anpassen, Statistiken aktualisieren, ausgewählte Spalten und Zeilen reduzieren oder große Schreibvorgänge stapeln. Wenn Sie eine Sofortmaßnahme benötigen, kann ein DBA vorübergehend einen bekanntermaßen guten Plan in Abfragespeicher erzwingen, während Sie die Grundursache beheben.

Verwenden von dbshell für interaktive Abfragen

Der Verwaltungsbefehl von dbshell Django öffnet eine interaktive SQL-Shell, die mit Ihrer Datenbank verbunden ist:

python manage.py dbshell

Das Backend verwendet sqlcmd, wenn Sie den Microsoft ODBC-Treiber konfigurieren, oder isql, wenn Sie FreeTDS verwenden. Überprüfen Sie, ob das Tool in Ihrem PATH ist:

  • Windows: sqlcmd ist in SQL Server Tools enthalten, oder Sie können sie separat herunterladen.
  • Linux und macOS: Installieren mssql-tools18 sie aus dem Microsoft Repository.