Az mssql-django hibaelhárítása

A SQL Serverhez, az Azure SQL Database-hez, az Azure SQL Managed Instance-hez és a Microsoft Fabricben található SQL-adatbázishoz készült mssql-django backenddel kapcsolatos gyakori problémák diagnosztizálása és megoldása.

Kapcsolódási problémák

Ez a szakasz a leggyakoribb csatlakozási hibákat és azok megoldását ismerteti.

Az ODBC-illesztő nem található

Tünetek:

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'")

Lehetséges okok és megoldások:

  • Az ODBC-illesztő nincs telepítve

    Telepítse a Microsoft ODBC-illesztőprogramot az SQL Serverhez. A letöltési hivatkozásokat lásd: Az SQL Serverhez készült ODBC-illesztőprogram letöltése.

  • Több illesztőprogram-verzió is telepítve van

    Adja meg az illesztőprogram pontos nevét vagy elérési útját a következő helyen 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",
            },
        },
    }
    

    Linuxon adja meg a teljes elérési utat:

    "OPTIONS": {
        "driver": "/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.6.1",
    },
    
  • Telepített illesztőprogramok ellenőrzése

    • Linux/macOS rendszeren futtassa a következőt odbcinst -q -d: .
    • Windows rendszeren ellenőrizze az ODBC-adatforrások elemet a Felügyeleti eszközök alatt.

Kapcsolat elutasítva

Tünetek:

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

Lehetséges okok és megoldások:

  • A TCP/IP nincs engedélyezve az SQL Serveren

    • Nyissa meg az SQL Server Konfigurációkezelőt.
    • Az SQL Server Hálózati konfigurációja alatt engedélyezze a(z) TCP/IP beállítást.
    • A TCP/IP-tulajdonságokban aktiválja a kapcsolathoz használt IP-címet.
    • Indítsa újra a SQL Server szolgáltatást.
  • Tűzfal blokkolja az 1433-at

    • Ellenőrizze, hogy a tűzfalszabályok engedélyezik-e a bejövő kapcsolatokat az 1433-as porton.
    • Az Azure SQL esetében adja hozzá az ügyfél IP-címét az Azure Portal tűzfalbeállításaiban.
  • Helytelen kiszolgálónév vagy port

    Ellenőrizze a konfigurációjában található HOST és PORT értékeket.

A bejelentkezés sikertelen

Tünetek:

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

Lehetséges okok és megoldások:

  • Helytelen hitelesítő adatok

    Ellenőrizze a felhasználónevet és a jelszót.

  • A felhasználó nem létezik

    Ellenőrizze, hogy a bejelentkezési fiók hozzá van-e rendelve egy felhasználóhoz a céladatbázisban.

  • SQL Server hitelesítés le van tiltva

    Vegyes módú hitelesítés engedélyezése, vagy Windows vagy Microsoft Entra hitelesítés használata.

Kapcsolati időkorlát

Tünetek:

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

Lehetséges okok és megoldások:

  • Hálózati késés

    Növelje a(z) connection_timeout értékét az OPTIONS menüben.

  • Kiszolgáló túlterhelt

    Növelje a connection_retries és a connection_retry_backoff_time értékét.

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

Migrálási problémák

Ezek a hibák a Django SQL Server elleni migrálási műveletei során fordulnak elő.

Raw SQL és GROUP BY problémák

Ezek a hibák akkor fordulnak elő, amikor a nyers vagy annotált, GROUP BY záradékot tartalmazó lekérdezések áthaladnak a háttérrendszer helyőrző-átírási lépésén.

IndexError GROUP BY esetén escape-elt %% és valós paraméterekkel

Tünetek:

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

A lekérdezés a GROUP BY záradék nélkül működik, és az escaped %% literal nélkül működik, de akkor kudarcot vall, ha mindkettő jelen van egy valós %s paraméter mellett.

Megoldás: Frissíts 1.7.4-re mssql-django vagy tovább. Az 1.7.4-es verzió a helykitöltők átírására szolgáló reguláris kifejezést kizárólag a %% és %s elemekre szűkíti, így az escape-elt %% literálok változatlanul megmaradnak, és nem kerülnek be fantom helykitöltők.

NotImplementedError ehhez: IntegerChoices nyers GROUP BY lekérdezésekben

Tünetek:

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

Ugyanez az enumérték működik az ORM-lekérdezésekben és a GROUP BY nélküli nyers lekérdezésekben is, de meghiúsul, ha paraméterként adják át egy GROUP BY záradékot tartalmazó nyers lekérdezésnek.

Megoldás: Frissíts 1.7.4-re mssql-django vagy tovább. Az 1.7.4-es verzió a paramétertípus-ellenőrzésekhez isinstance-t használ a(z) GROUP BY útvonalon, így a(z) IntegerChoices (a int egyik alosztálya) megfelelően kötődik. bool továbbra is kötődik BIT, és a sima int változatlan marad.

Dátum- és időproblémák

Now() értékek eltolódnak, ha USE_TZ=True

Tünetek:

A Django Now(), auto_now vagy auto_now_add által írt időbélyegek eltolódnak, ha az SQL Server hoszt időzónája nem UTC.

Megoldás: Frissítsen az mssql-django 1.7.2-re vagy újabb verzióra. Az 1.7.2-es verzió kijavítja az időzóna-alapú Now() SQL-generálást és a datetimeoffset eltoláskezelést.

AttributeError híváskor .explain()

Tünetek:

AttributeError: ... explain_format ...

Megoldás: Frissítsen az mssql-django 1.7.2-re vagy újabb verzióra. Az 1.7.2-es verzió kijavítja a Django 4.0-s és újabb verzióinak fordítókompatibilitását, és elmagyarázza a metaadatokat.

Az automatikus mező nem módosítható

Tünetek:

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

Megoldás: SQL Server nem támogatja egy mező módosítását a mezőről a másikraAutoField. Hozzon létre egy új modellt a kívánt mezőtípussal, migrálja manuálisan az adatokat, majd dobja el a régi táblát. A kerülőmegoldásokkal kapcsolatban lásd: Adatbázis-migrációk az mssql-django használatával.

Az átnevezés idegenkulcs-megszorítás miatt sikertelen

Tünetek:

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

Megoldás: SQL Server az oszlopok átnevezése előtt el kell dobni az idegenkulcs-korlátozásokat. Használja SeparateDatabaseAndState a migrálás során. Például lásd a következőt: Database migrations with mssql-django.

Kódolási problémák

Kódolási hibák általában akkor fordulnak elő, ha pyodbc helytelenül értelmezi SQL Server karakteradatait.

Unicode kódolási hibák

Tünetek:

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

Megoldás: Kódolás konfigurálása pyodbc a OPTIONS szótárban:

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

FreeTDS-problémák

A FreeTDS speciális konfigurációt igényel, amely eltér a Microsoft ODBC-illesztőtől.

host_is_server hiba

Tünetek:

A kapcsolat meghiúsul, ha a FreeTDS használatakor nincs megadva a host_is_server.

Megoldás: Állítsa be host_is_server a True FreeTDS használatakor:

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

A FreeTDS konfigurálásáról további információt az mssql-django kapcsolati beállításai című témakörben talál.

Adatbázissal kapcsolatos problémák tesztelése

Az adatbázis létrehozásának és megsemmisítésének tesztelése a hitelesítési módszertől függően meghiúsulhat.

Nem hozható létre tesztadatbázis felügyelt identitással

Tünetek:

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

Or:

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

A tesztfuttató nem tudja létrehozni vagy megsemmisíteni a tesztadatbázist a (felügyelt identitás) hitelesítés használatakor ActiveDirectoryMsi . Ez a korlátozás azért létezik, mert:

  • A felügyelt identitás hitelesítő adatai a gazdakörnyezetből kérhetők le (például Azure virtuális gépről vagy az App Service-ből).

  • A tesztfuttató a lebontási szakasz során a test adatbázis hitelesítő adataival próbál csatlakozni.

  • A felügyelt identitások adatbázisszintű szerepköröket kaphatnak, de az adatbázis-létrehozás és -törlés teszteléséhez általában kiszolgálószintű engedélyekre van szükség, amelyekkel a tesztfuttatók gyakran nem rendelkeznek.

Érintett hitelesítési módszerek:

  • ActiveDirectoryMsi (Azure által felügyelt identitás)
  • ActiveDirectoryServicePrincipal (ha csak a kiszolgáló hatókörében van konfigurálva)

Támogatott hitelesítési módszerek (az adatbázis létrehozásának tesztelése működik):

  • ActiveDirectoryPassword
  • ActiveDirectoryIntegrated
  • SQL-hitelesítés (felhasználónév/jelszó)

Hitelesítési kompromisszumok tesztelési környezetekhez

Method Titok nélküli Működik az automatikus tesztadatbázis-létrehozással és -törléssel Tipikus használat
ActiveDirectoryMsi Yes Általában nem (kivéve, ha kiszolgálószintű jogosultságok vannak megadva) Azure-ban üzemeltetett éles számítási feladatok
ActiveDirectoryServicePrincipal Nem (titkos ügyfélkód/tanúsítvány) A megadott kiszolgálószintű jogosultságoktól függ CI/CD explicit identitáskezeléssel
ActiveDirectoryPassword No Igen (megfelelő SQL-engedélyekkel) Fejlesztői és szabályozott CI-környezetek
SQL-hitelesítés No Igen (megfelelő SQL-engedélyekkel) Helyi vagy izolált tesztkörnyezetek

Megoldások:

  • Fejlesztéshez: A jelölő használatával --keepdb kihagyhatja a tesztadatbázisok lebontását:

    python manage.py test --keepdb
    
  • CI/CD-folyamatok esetén: Hozzon létre előre egy dedikált tesztadatbázist, és adja meg a felügyelt identitást CREATE TABLE és ALTER engedélyeket:

    -- 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];
    
  • Alternatíva: Használjon SQL-hitelesítést tesztkörnyezetekben, vagy a CI/CD tesztfuttatókhoz váltson át a(z) ActiveDirectoryPassword használatára.

Visszaállítási eljárások

Ha egy migrálás részben meghiúsul, használja ezt a visszaállítási sorozatot egy ismert jó állapotba való visszatéréshez:

  1. Az alkalmazás írásának leállítása a további sémaeltolódás elkerülése érdekében.

  2. Migrálási állapot vizsgálata:

    python manage.py showmigrations
    python manage.py sqlmigrate <app_label> <migration_number>
    
  3. Álljon vissza a legutóbb ismerten jó migrációra:

    python manage.py migrate <app_label> <previous_migration>
    
  4. Ha a séma és az áttelepítési előzmények eltérnek, csak a tényleges adatbázisséma ellenőrzése után javítsa ki gondosan --fake az állapotot.

  5. Először futtassa újra a migrációkat egy tesztkörnyezetben, majd próbálja meg újra élesben.

Important

Az olyan romboló migrálások esetében, mint az elvetés, az átnevezés és az oszloptípus módosítása, az üzembe helyezés előtt készítsen egy tesztelt biztonsági másolatot. Ha a migrálással történő visszaállítás nem lehetséges, állítsa vissza a biztonsági másolatból, és alkalmazza újra az érvényesített migrálásokat.

Docker- és tárolóproblémák

A tárolóképek külön ODBC-illesztőprogram-telepítést és fordítási függőségeket igényelnek.

Az ODBC-illesztő nem található a tárolóban

Tünetek:

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

Lehetséges okok és megoldások:

  • Az ODBC-illesztő nincs telepítve a tároló lemezképében

    A Slim vagy Alpine alapképek nem tartalmazzák az ODBC-illesztőprogramot. Adja hozzá az Microsoft APT-adattárat, és telepítse msodbcsql18 a Dockerfile-ban. Tekintse meg az App Service-ben való üzembe helyezést egy teljes Dockerfile-példáért.

  • Hiányzó unixodbc-dev csomag

    A pyodbc kerék a libodbc.so ellen van linkelve. A Python-csomagok telepítése előtt telepítse a(z) unixodbc-dev csomagot (Debian/Ubuntu rendszeren) vagy a(z) unixODBC-devel csomagot (RHEL/Fedora rendszeren).

pyodbc nem tud vékony képekre építeni

Tünetek:

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

Or:

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

Megoldás: Telepítse a fordításhoz szükséges függőségeket a(z) pip install előtt:

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

Másik lehetőségként használjon többfázisú buildet a végső kép kicsiben tartásához:

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

A tároló nem tud csatlakozni SQL Server

Tünetek:

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

Lehetséges okok és megoldások:

  • A Docker Compose szolgáltatásneve nincs gazdagépként használva

    A Docker Compose használatakor állítsa a(z) DB_HOST értékét a szolgáltatás nevére (például db), ne pedig localhost vagy 127.0.0.1 értékre.

  • SQL Server tároló nem áll készen

    A SQL Server tároló elindítása több másodpercet vesz igénybe. Állapot-ellenőrzés vagy indítási késleltetés hozzáadása:

    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
    
  • Portleképezési ütközések

    Ha egy másik SQL Server-példány fut a gazdagépen, módosítsa a közzétett portot (például 1434:1433) és ennek megfelelően frissítse a Django-konfigurációt.

Azure SQL átmeneti hiba helyreállítása

A mssql-django háttérrendszer a lekérdezéssel SERVERPROPERTY('EngineEdition')automatikusan észleli Azure SQL Database és Azure SQL Managed Instance kapcsolatokat. Azure SQL használata esetén a háttérrendszer átmeneti hibák, például ideiglenes erőforráskorlátok vagy rövid hálózati megszakítások esetén újrapróbálja a csatlakozást.

Ezt a viselkedést a connection_retries és connection_retry_backoff_time beállításokkal finomhangolhatja:

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

Ezek a beállítások csak a kezdeti kapcsolatlétrehozásra vonatkoznak. A háttérrendszer nem próbálkozik újra a sikertelen lekérdezésekkel. Ha egy lekérdezés a kapcsolat létrejötte után átmeneti hibával meghiúsul, a kivétel az alkalmazás kódjába kerül. Az alkalmazásszintű újrapróbálkozás logikáját (például django-retry-db vagy egyéni köztes szoftver) használja a lekérdezésszintű rugalmasság érdekében.

Lassú lekérdezések és regressziók tervezése

Ezekhez a problémákhoz általában kiszolgálóoldali elemzésre van szükség a Django-szintű lekérdezések áttekintésével együtt.

A lekérdezés lelassul, vagy időtúllépésbe fut

Tünetek:

Ugyanez a lekérdezéskészlet idővel lassabbá válik, vagy az üzembe helyezés, az index módosítása vagy a statisztikák frissítése után elindul az időzítés.

Lehetséges okok és megoldások:

  • Kezdés beépített teljesítményjelentésekkel

    SQL Server és Azure SQL Managed Instance esetén nyissa meg a Teljesítmény irányítópultot SQL Server Management Studio. Az Azure SQL Database esetében nyissa meg a Azure SQL Database lekérdezési teljesítményének elemzését. Ezek az eszközök általában jobb első lépés, mint az alkalmi DMV-lekérdezések, mert gyorsan felszínre kerülnek a költséges lekérdezések, várakozások és erőforrás-nyomás.

  • Regresszió megtervezése

    A Query Store használatával keresse meg a lassú lekérdezést, és ellenőrizze, hogy több végrehajtási terve van-e. Kezdje a regressziós lekérdezésekkel és a leggyakoribb erőforrás-használó lekérdezésekkel, amelyek a számítási feladatok Query Store való monitorozásának ajánlott eljárásaiban olvashatók.

  • Nem hatékony végrehajtási terv

    Nyisson meg egy tényleges végrehajtási tervet az utasításhoz, és ellenőrizze, hogy vannak-e tábla- vagy indexvizsgálatok, nagy kulcskeresések, kivonatkiömlések vagy pontatlan sorbecslések. A háttérről a Végrehajtási terv áttekintése című témakörben olvashat.

  • Hibás szűk keresztmetszetet azonosítottak

    Ha a lekérdezés nem CPU-korlátos, használja a Query Store várakozási statisztikáit és a szűk keresztmetszetek azonosítása funkciót a processzor, a memória, a lemez-I/O, a blokkolás és a kapcsolatterhelés megkülönböztetésére.

  • Nem a megfelelő rétegben alkalmazott javítás

    Alkalmazza a legkisebb hatékony javítást: adjon hozzá vagy módosítson indexeket, frissítse a statisztikákat, csökkentse az érintett oszlopok és sorok számát, vagy kötegelje a nagy mennyiségű írási műveleteket. Ha vészhelyzeti megoldásra van szüksége, a DBA ideiglenesen kényszeríthet egy ismert jó tervet Query Store, miközben kijavítja a kiváltó okot.

A dbshell használata interaktív lekérdezésekhez

A Django dbshell kezelőparancsa megnyit egy, az adatbázisához kapcsolódó interaktív SQL-parancssort:

python manage.py dbshell

A háttérrendszer sqlcmd használ, amikor a Microsoft ODBC-illesztőprogramot konfigurálja, vagy isql elemet, amikor a FreeTDS-t használja. Ellenőrizze, hogy az eszköz a PATH-on van-e:

  • Windows: sqlcmd SQL Server eszközök részét képezi, vagy külön is letöltheti.
  • Linux és macOS: Telepítés mssql-tools18 a Microsoft adattárból.