Řešení potíží s mssql-django

Diagnostika a řešení běžných problémů s back-endem mssql-django pro SQL Server, Azure SQL Database, Azure SQL Managed Instance a databází SQL v Microsoft Fabric

Problémy s připojením

Tato část se věnuje nejběžnějším chybám připojení a jejich řešení.

Ovladač ODBC nebyl nalezen.

Příznaky:

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žné příčiny a řešení:

  • Ovladač ODBC není nainstalován.

    Nainstalujte ovladač MICROSOFT ODBC pro SQL Server. Odkazy ke stažení naleznete v tématu Stažení ovladače ODBC pro SQL Server.

  • Nainstalovaných více verzí ovladačů

    Zadejte přesný název nebo cestu ovladače v 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",
            },
        },
    }
    

    V Linuxu zadejte úplnou cestu:

    "OPTIONS": {
        "driver": "/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.6.1",
    },
    
  • Kontrola nainstalovaných ovladačů

    • V Linuxu nebo macOS spusťte odbcinst -q -dpříkaz .
    • Na Windows zkontrolujte zdroje dat ODBC v nástrojích pro správu.

Odmítnuté připojení

Příznaky:

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

Možné příčiny a řešení:

  • Na SQL Server není povolený protokol TCP/IP

    • Otevřete nástroj SQL Server Configuration Manager.
    • V části SQL Server Konfigurace sítě povolte protokol TCP/IP.
    • Ve vlastnostech protokolu TCP/IP aktivujte IP adresu použitou pro připojení.
    • Restartujte službu SQL Server.
  • Brána firewall blokující port 1433

    • Ověřte, že pravidla brány firewall povolují příchozí připojení na portu 1433.
    • Pro Azure SQL přidejte IP adresu klienta do nastavení brány firewall portálu Azure.
  • Nesprávný název serveru nebo port

    Ověřte hodnoty HOST a PORT ve své konfiguraci.

Přihlášení se nezdařilo.

Příznaky:

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

Možné příčiny a řešení:

  • Nesprávné přihlašovací údaje

    Ověřte uživatelské jméno a heslo.

  • Uživatel neexistuje.

    Ověřte, že je přihlášení namapované na uživatele v cílové databázi.

  • SQL Server ověřování zakázáno

    Povolte ověřování ve smíšeném režimu nebo použijte ověřování Windows nebo Microsoft Entra.

Časový limit připojení vypršel

Příznaky:

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

Možné příčiny a řešení:

  • Latence sítě

    Zvyšte connection_timeout v nabídce MOŽNOSTI.

  • Server přetížený

    Zvýšit connection_retries a connection_retry_backoff_time.

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

Problémy s migrací

K těmto chybám dochází během operací migrace Django proti SQL Server.

Problémy s datem a časem

hodnoty Now() jsou posunuty, když USE_TZ=True

Příznaky:

Časová razítka zapsaná pomocí Django Now(), auto_now nebo auto_now_add jsou posunutá, pokud časové pásmo hostitele SQL Serveru není nastaveno na UTC.

Řešení: Upgradujte na mssql-django verzi 1.7.2 nebo novější. Verze 1.7.2 opravuje generování Now() SQL zohledňující časová pásma a zpracování posunu u datetimeoffset.

AttributeError při volání .explain()

Příznaky:

AttributeError: ... explain_format ...

Řešení: Upgradujte na mssql-django verzi 1.7.2 nebo novější. Verze 1.7.2 opravuje kompatibilitu kompilátoru pro Django 4.0 a novější vysvětluje metadata.

Nelze změnit automatické pole

Příznaky:

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

Řešení: SQL Server nepodporuje změnu pole z nebo do AutoField. Vytvořte nový model s požadovaným typem pole, migrujte data ručně a potom zahoďte starou tabulku. Alternativní řešení najdete v tématu Migrace databází pomocí mssql-django.

Přejmenování selže kvůli omezení cizího klíče

Příznaky:

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

Řešení: SQL Server před přejmenováním sloupců vyžaduje vyřazení omezení cizího klíče. Použijte SeparateDatabaseAndState při migraci. Příklad najdete v tématu Migrace databází s mssql-django.

Problémy s kódováním

K chybám kódování obvykle dochází, když pyodbc nesprávně interpretuje data znaků z SQL Server.

Chyby kódování Unicode

Příznaky:

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

Řešení: Konfigurace pyodbc kódování ve slovníku OPTIONS :

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

Problémy s freeTDS

FreeTDS vyžaduje konkrétní konfiguraci, která se liší od ovladače ODBC Microsoft.

Chyba host_is_server

Příznaky:

Připojení selže při použití FreeTDS bez zadání host_is_server.

Řešení: Nastavte host_is_server na True , když používáte FreeTDS:

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

Další informace o konfiguraci FreeTDS naleznete v tématu Možnosti připojení pro mssql-django.

Problémy s testovací databází

Vytvoření a zničení testovací databáze může selhat v závislosti na metodě ověřování.

Nejde vytvořit testovací databázi se spravovanou identitou

Příznaky:

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

Or:

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

Při použití ověřování pomocí ActiveDirectoryMsi (spravované identity) se spouštěči testů nepodaří vytvořit ani odstranit testovací databázi. Toto omezení existuje, protože:

  • Přihlašovací údaje spravované identity se získávají z hostitelského prostředí (například z virtuálního počítače Azure a ze služby App Service).

  • Spouštěč testů se během ukončování pokusí připojit pomocí přihlašovacích údajů k databázi test.

  • Spravované identitě je možné udělit role na úrovni databáze, ale vytvoření a odstranění testovací databáze obvykle vyžaduje oprávnění na úrovni serveru, která testovací spouštěče často nemají.

Ovlivněné metody ověřování:

  • ActiveDirectoryMsi (spravovaná identita Azure)
  • ActiveDirectoryServicePrincipal (pouze při konfiguraci na úrovni serveru)

Podporované metody ověřování (funguje vytváření testovací databáze):

  • ActiveDirectoryPassword
  • ActiveDirectoryIntegrated
  • Ověřování SQL (uživatelské jméno a heslo)

Kompromisy ověřování pro testovací prostředí

Metoda Bez tajemství Funguje s automatickým vytvářením a odstraňováním testovací databáze. Typické použití
ActiveDirectoryMsi Yes Obvykle ne (pokud nejsou udělena práva na úrovni serveru). produkční úlohy hostované Azure
ActiveDirectoryServicePrincipal Ne (tajný klíč klienta nebo certifikát) Závisí na udělených právech na úrovni serveru. CI/CD s explicitní správou identit
ActiveDirectoryPassword No Ano (s dostatečnými oprávněními SQL) Vývojová a řízená prostředí CI
Ověřování SQL No Ano (s dostatečnými oprávněními SQL) Místní nebo izolovaná testovací prostředí

Řešení:

  • Pro vývoj: Použijte příznak --keepdb, chcete-li přeskočit odstranění testovací databáze:

    python manage.py test --keepdb
    
  • Pro CI/CD kanály: Předem vytvořte vyhrazenou testovací databázi a udělte spravované identitě oprávnění CREATE TABLE a 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: Pro testovací prostředí použijte ověřování SQL Serveru nebo přejděte na ActiveDirectoryPassword pro spouštěče testů CI/CD.

Postupy vrácení zpět

Pokud migrace v průběhu selže, použijte tento postup vrácení zpět pro návrat do známého funkčního stavu:

  1. Zastavte zápisy aplikací, abyste se vyhnuli dalším posunům schématu.

  2. Kontrola stavu migrace:

    python manage.py showmigrations
    python manage.py sqlmigrate <app_label> <migration_number>
    
  3. Vraťte se k poslední známé dobré migraci:

    python manage.py migrate <app_label> <previous_migration>
    
  4. Pokud se schéma a historie migrací rozcházejí, opravte stav opatrně pomocí --fake až po ověření skutečného schématu databáze.

  5. Nejprve znovu spusťte migrace v testovacím prostředí a potom to zkuste znovu v produkci.

Important

V případě destruktivních migrací, jako je vyřazení, přejmenování a změny typu sloupce, proveďte před nasazením otestované zálohování. Pokud není možné vrátit změny pomocí migrace, obnovte systém ze zálohy a znovu použijte ověřené migrace.

Problémy s Dockerem a kontejnerem

Kontejnerové image vyžadují explicitní instalaci ovladače ODBC a závislosti potřebné k sestavení.

Ovladač ODBC nebyl v kontejneru nalezen.

Příznaky:

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

Možné příčiny a řešení:

  • Ovladač ODBC není nainstalovaný v imagi kontejneru

    Základní obrazy Slim nebo Alpine neobsahují ovladač ODBC. Přidejte do souboru Dockerfile repozitář Microsoft APT a nainstalujte msodbcsql18. Kompletní příklad souboru Dockerfile najdete v tématu Nasazení do služby App Service .

  • Chybějící unixodbc-dev balíček

    pyodbc wheel je linkován proti libodbc.so. Před instalací balíčků Python nainstalujte unixodbc-dev (Debian/Ubuntu) nebo unixODBC-devel (RHEL/Fedora).

Pyodbc se nepovede vytvářet na tenkých obrázcích

Příznaky:

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

Or:

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

Řešení: Nainstalujte závislosti pro sestavení před pip install:

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

Případně můžete použít vícefázové sestavení, abyste zachovali konečnou image v malém rozsahu:

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

Kontejner se nemůže připojit k SQL Server

Příznaky:

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

Možné příčiny a řešení:

  • Název služby Docker Compose se nepoužívá jako hostitel

    Pokud používáte Docker Compose, nastavte DB_HOST na název služby (například db), ne localhost nebo 127.0.0.1.

  • SQL Server kontejner není připravený

    Spuštění kontejneru SQL Server trvá několik sekund. Přidejte kontrolu stavu nebo zpoždění spuštění:

    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 mapování portů

    Pokud na hostiteli běží jiná instance SQL Server, změňte vystavený port (například1434:1433) a odpovídajícím způsobem aktualizujte konfiguraci Django.

Azure SQL obnovení po přechodných chybách

Backend mssql-django automaticky rozpozná připojení ke službám Azure SQL Database a Azure SQL Managed Instance pomocí dotazu na SERVERPROPERTY('EngineEdition'). Při běhu v prostředí Azure SQL backend při přechodných chybách opakuje pokusy o připojení (například při dočasných omezeních prostředků nebo krátkodobých výpadcích sítě).

Toto chování můžete upravit pomocí voleb connection_retries a connection_retry_backoff_time:

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

Tato nastavení platí jenom pro počáteční připojení. Back-end neopakuje neúspěšné dotazy. Pokud dotaz po vytvoření připojení selže s přechodnou chybou, výjimka se rozšíří do kódu aplikace. K zajištění odolnosti na úrovni dotazů použijte logiku opakování na úrovni aplikace (například django-retry-db nebo vlastní middleware).

Pomalé dotazy a regrese plánů

Tyto problémy obvykle potřebují analýzu na straně serveru spolu s kontrolou dotazů na úrovni Django.

Dotaz se zpomaluje nebo začne narážet na časový limit.

Příznaky:

Stejná sada dotazů se postupem času zpomaluje nebo po nasazení, změně indexu či aktualizaci statistik začne narážet na časový limit.

Možné příčiny a řešení:

  • Začínáme s integrovanými sestavami výkonu

    Pro SQL Server a Azure SQL Managed Instance otevřete v aplikaci SQL Server Management Studio Řídicí panel výkonu. Pro Azure SQL Database otevřete Query Performance Insight pro Azure SQL Database. Tyto nástroje jsou obvykle lepším prvním krokem než ad hoc dotazy DMV, protože rychle zobrazují nákladné dotazy, čekání a tlak na prostředky.

  • Regrese plánu

    Pomocí Query Store vyhledejte pomalý dotaz a zkontrolujte, jestli má více plánů. Začněte zobrazeními Dotazy se zhoršeným výkonem a Dotazy s nejvyšší spotřebou prostředků, která jsou popsána v osvědčených postupech pro monitorování úloh pomocí Query Store.

  • Neefektivní plán provádění

    Otevřete skutečný plán provádění příkazu a zkontrolujte prohledávání tabulek nebo indexů, rozsáhlé vyhledávání klíčů, přelití hodnot hash nebo nepřesné odhady řádků. Základní informace najdete v tématu Přehled plánu provádění.

  • Bylo identifikováno nesprávné úzké místo

    Pokud dotaz není vázán na procesor, použijte Query Store statistiky čekání a identifikujte kritické body k rozlišení procesoru, paměti, vstupně-výstupních operací disku, blokování a tlaku připojení.

  • Oprava použitá v nesprávné vrstvě

    Použijte nejmenší efektivní opravu: přidejte nebo upravte indexy, aktualizujte statistiky, snižte vybrané sloupce a řádky nebo dávkové velké zápisy. Pokud potřebujete nouzové zmírnění dopadů, může správce DBA dočasně vynutit známý funkční plán v Query Store, zatímco odstraníte hlavní příčinu.

Použití dbshellu pro interaktivní dotazy

Příkaz pro správu Django dbshell otevře interaktivní prostředí SQL připojené k vaší databázi:

python manage.py dbshell

Backend používá sqlcmd, když nakonfigurujete ovladač Microsoft ODBC, nebo isql, když používáte FreeTDS. Ověřte, že je nástroj ve vaší cestě:

  • Windows: sqlcmd je součástí nástrojů SQL Server nebo si ho můžete stáhnout samostatně.
  • Linux a macOS: Nainstalujte mssql-tools18 z úložiště Microsoft.