Felhantering och SQLSTATE-koder för mssql-python

mssql-python-drivrutinen definierar en standardiserad undantagshierarki, vanliga felhanteringsmönster och SQLSTATE-kodmappningar för SQL Server och Azure SQL.

Undantagshierarki

mssql-python-drivrutinen följer DB-API 2.0 (PEP 249) undantagshierarkin:

Exception (builtins)
├── Warning
└── Error
    ├── InterfaceError
    └── DatabaseError
        ├── DataError
        ├── OperationalError
        ├── IntegrityError
        ├── InternalError
        ├── ProgrammingError
        └── NotSupportedError

ConnectionStringParseError (standalone, not part of hierarchy)

Undantagsbeskrivningar

Fånga det mest specifika undantaget som passar din situation. Till exempel, fånga IntegrityError begränsningsbrott på INSERT/UPDATE operationer och ProgrammingError SQL-syntaxproblem under utveckling. Fånga basklassen Error endast som en reservplan.

Exception När det höjs
Warning Icke-dödliga varningar från databasen.
Error Basklass för alla databasfel.
InterfaceError Fel relaterade till databasgränssnittet (drivrutinen), inte databasen i sig.
DatabaseError Fel relaterade till databasen.
DataError Fel på grund av problem med bearbetade data (division med noll, värde utanför intervallet).
OperationalError Fel relaterade till databasens drift (anslutning förlorad, minnesallokering, transaktionsfel).
IntegrityError Fel när databasintegriteten påverkas (främmande nyckelbrott, unik begränsning).
InternalError Interna databasfel (markören är inte giltig, transaktionen är ur synk).
ProgrammingError Programmeringsfel (syntaxfel, tabell ej hittad, fel antal parametrar).
NotSupportedError Funktion som inte stöds av databasen eller drivrutinen.
ConnectionStringParseError Ogiltig reťazec pripojenia-syntax eller okända nyckelord.

Grundläggande felhantering

Använd try-except-block för att hantera databasfel:

import mssql_python

try:
    conn = mssql_python.connect(connection_string)
    cursor = conn.cursor()
    cursor.execute("INSERT INTO Production.Product (Name) VALUES (%(name)s)", {"name": "Test"})
    conn.commit()
except mssql_python.IntegrityError as e:
    print(f"Constraint violation: {e}")
    conn.rollback()
except mssql_python.ProgrammingError as e:
    print(f"SQL syntax error: {e}")
except mssql_python.OperationalError as e:
    print(f"Connection or operational error: {e}")
except mssql_python.Error as e:
    print(f"Database error: {e}")
finally:
    if 'conn' in locals():
        conn.close()

Åtkomstundantag via anslutningen

Du kan fånga undantag via anslutningsinstansen:

try:
    cursor.execute("INVALID SQL")
except conn.ProgrammingError as e:
    print(f"Caught via connection: {e}")

Felmeddelandestruktur

MSSQL-Python undantagsobjekt exponerar tre attribut som kommer från drivrutinens Exception basklass:

Attribute Källa Beskrivning
driver_error Python-drivrutin Standardiserad engelsk text vald av SQLSTATE returnerades från ODBC (till exempel "Communication link failure", "Invalid authorization specification", ). "Syntax error or access violation" Stabil över utgåvor; Säkert att matcha substrängen.
ddbc_error Direkt databasanslutning (DDBC) Servermeddelandet, vanligtvis prefixet med [Microsoft][SQL Server]. Format är inte ett stabilt kontrakt.
message Består f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". Det är detta som str(exc) återvänder.
try:
    cursor.execute("SELECT * FROM no_such_table;")
except mssql_python.ProgrammingError as exc:
    print(exc.driver_error)  # Base table or view not found
    print(exc.ddbc_error)    # [Microsoft][SQL Server]Invalid object name 'no_such_table'.
    print(exc)               # Driver Error: Base table or view not found; DDBC Error: ...

SQL Server-motorns felnummer (såsom 208 eller 40501) exponeras inte som ett attribut och är inte pålitligt inbäddat i någon av strängarna. Klassificera fel efter undantagsunderklass plus driver_error text. För Azure SQL-throttling, se Retry logic.

SQLSTATE-klassificering

mssql-python använder SQLSTATE som ODBC returnerar för att välja både Python-undantagsunderklassen och textendriver_error. Den fullständiga SQLSTATE-→ undantagskartläggningen finns i exceptions.py drivrutinskällkoden. Nästa avsnitt listar de SQLSTATES som oftast förekommer med SQL Server och Azure SQL.

Anslutningsfel

Anslutningsfel från mssql_python.connect() raise mssql_python.OperationalError, samma som andra anslutningsfel:

import mssql_python

try:
    conn = mssql_python.connect(
        "Server=unreachable-server.database.windows.net;"
        "Database=<database>;"
        "Authentication=ActiveDirectoryDefault;"
        "Encrypt=yes"
    )
except mssql_python.OperationalError as e:
    print(f"Connection failed: {e.driver_error}")
    # e.driver_error: "Client unable to establish connection"

Fel i anslutningssträngen

Misstag i anslutningssträngsparsning ger upphov till ConnectionStringParseError:

try:
    conn = mssql_python.connect("Servr=localhost;")  # Typo
except mssql_python.ConnectionStringParseError as e:
    print(f"Invalid connection string: {e}")
    # Output: Unknown keyword 'Servr'

SQLSTATE-kodreferens

SQLSTATE-koder är femteckenskoder som identifierar felförhållanden. De två första tecknen anger klassen, och de sista tre anger underklassen. Du behöver sällan inspektera dessa regler direkt. Fånga istället rätt Python-undantagstyp (listad i kolumnen "Exception"). Använd SQLSTATE-koder när du behöver skilja mellan specifika felförhållanden inom samma undantagstyp, till exempel för att skilja en deadlock (40001) från ett allmänt anslutningsfel (08S01).

Klass 00 - Lyckad avslutning

SQLSTATE Exception Beskrivning
00000 None Success

Klass 01 - Varning

SQLSTATE Exception Beskrivning
01000 Varning Allmän varning
01001 Varning Marköråtgärdskonflikt
01002 Varning Frånkopplingsfel
01003 DataError NULL-värde som eliminerats i set-funktionen
01004 DataError Strängdata, höger trunkering
01006 Varning Behörigheten har inte återkallats
01007 Varning Behörighet har inte beviljats
01S00 Varning Attributet ogiltig reťazec pripojenia
01S01 Varning Fel i rad
01S02 Varning Alternativvärdet har ändrats

Klass 07 - Dynamiskt SQL-fel

SQLSTATE Exception Beskrivning
07001 ProgrammingError Fel antal parametrar
07002 ProgrammingError Antal fält är felaktigt
07005 ProgrammingError Prepared-satsen, inte en markörspecifikation
07006 ProgrammingError Attributöverträdelse för begränsad datatyp
07009 ProgrammingError Ogiltigt deskriptorindex
07S01 ProgrammingError Ogiltig användning av standardparameter

Klass 08 - Anslutningsundantag

SQLSTATE Exception Beskrivning
08001 OperationalError Klient kan inte upprätta anslutning
08002 OperationalError Anslutningsnamn i bruk
08003 OperationalError Koppling existerar inte
08004 OperationalError Servern avvisade anslutningen
08007 OperationalError Anslutningsfel under transaktion
08S01 OperationalError Kommunikationslänkfel

Klass 21 - Kardinalitetsöverträdelse

SQLSTATE Exception Beskrivning
21S01 ProgrammingError Värdelistan för infogning matchar inte kolumnlistan
21S02 ProgrammingError Graden av härledd tabell matchar inte kolumnlistan

Klass 22 - Dataundantag

SQLSTATE Exception Beskrivning
22001 DataError Strängdata, höger trunkering
22002 DataError Indikatorvariabel krävs men tillhandahålls inte
22003 DataError Numeriskt värde som ligger utom intervallet
22007 DataError Ogiltigt datetime-format
22008 DataError Datetime-fältspill
22012 DataError Division med noll
22015 DataError Intervallfältsspill
22018 DataError Ogiltigt teckenvärde för gjuten specifikation
22019 DataError Ogiltigt escape-tecken
22025 DataError Ogiltig escape-sekvens
22026 DataError Strängdata, längdmatchningsfel

Klass 23 - Integritetsbegränsningsbrott

SQLSTATE Exception Beskrivning
23000 Integritetsfel Integritetsbegränsningsbrott (allmänt)

Klass 24 - Ogiltigt markörtillstånd

SQLSTATE Exception Beskrivning
24000 Internfel Ogiltigt markörtillstånd

Klass 25 - Ogiltigt transaktionstillstånd

SQLSTATE Exception Beskrivning
25000 OperationalError Ogiltigt transaktionstillstånd
25S01 OperationalError Transaktionstillstånd okänt
25S02 OperationalError Transaktionen är fortfarande aktiv
25S03 OperationalError Transaktionen rullas tillbaka

Klass 28 - Specifikation för ogiltig auktorisation

SQLSTATE Exception Beskrivning
28000 OperationalError Ogiltig auktoriseringsspecifikation (inloggning misslyckades)

Klass 34 - Ogiltigt markörnamn

SQLSTATE Exception Beskrivning
34000 ProgrammingError Ogiltigt markörnamn

Klass 3C - Dubblettpekornamn

SQLSTATE Exception Beskrivning
3C000 ProgrammingError Duplicerat markörnamn

Klass 3D - Ogiltigt katalognamn

SQLSTATE Exception Beskrivning
3D000 ProgrammingError Ogiltigt katalognamn

Klass 3F - Ogiltigt schemanamn

SQLSTATE Exception Beskrivning
3F000 ProgrammingError Ogiltigt schemanamn

Klass 40 - Transaktionsåterställning

SQLSTATE Exception Beskrivning
40001 OperationalError Serialiseringsfel (deadlock)
40002 OperationalError Integritetsbegränsningsbrott orsakade rollback
40003 OperationalError Slutförande av instruktion okänd

Klass 42 - Syntaxfel eller överträdelse av åtkomstregeln

SQLSTATE Exception Beskrivning
42000 ProgrammingError Syntaxfel eller åtkomstöverträdelse
42S01 ProgrammingError Bastabellen eller vyn finns redan
42S02 ProgrammingError Det går inte att hitta bastabellen eller vyn
42S11 ProgrammingError Indexet finns redan
42S12 ProgrammingError Det går inte att hitta indexet
42S21 ProgrammingError Kolumnen finns redan
42S22 ProgrammingError Det går inte att hitta kolumnen

Klass 44 - MED KRYSSALTERNATIV överträdelse

SQLSTATE Exception Beskrivning
44000 Integritetsfel MED KONTROLLALTERNATIVsöverträdelse

Klass HY - CLI-specifikt tillstånd

SQLSTATE Exception Beskrivning
HY000 DatabaseError Allmänt fel
HY001 OperationalError Fel vid minnesallokering
HY003 ProgrammingError Ogiltig applikationsbufferttyp
HY004 ProgrammingError Ogiltig SQL-datatyp
HY007 ProgrammingError Tillhörande uttalande är inte förberett
HY008 OperationalError Åtgärden avbröts
HY009 ProgrammingError Ogiltig användning av null-pekare
HY010 ProgrammingError Funktionssekvensfel
HY011 ProgrammingError Attributet kan inte sättas nu
HY012 ProgrammingError Ogiltig transaktionskod
HY013 OperationalError Minneshanteringsfel
HY014 OperationalError Gräns för antal handtag som överskrids
HY015 ProgrammingError Inget markörnamn tillgängligt
HY016 ProgrammingError Kan inte ändra en radbeskrivare för implementeringen
HY017 ProgrammingError Ogiltig användning av automatiskt tilldelad deskriptorhandtag
HY018 OperationalError Servern avvisade avbrytningsbegäran
HY019 ProgrammingError Icke-tecken- och icke-binär data skickades i delar
HY020 DataError Försök att sammanfoga ett nollvärde
HY021 ProgrammingError Inkonsekvent beskrivningsinformation
HY024 ProgrammingError Ogiltigt attributvärde
HY090 ProgrammingError Ogiltig sträng- eller buffertlängd
HY091 ProgrammingError Ogiltig beskrivarfältidentifierare
HY092 ProgrammingError Ogiltig attribut-/optionsidentifierare
HY095 ProgrammingError Funktionstyp utanför räckvidden
HY096 ProgrammingError Ogiltig informationstyp
HY097 ProgrammingError Kolonntyp utanför räckvidden
HY098 ProgrammingError Teleskoptyp utanför räckvidden
HY099 ProgrammingError Nullbar typ utanför räckvidd
HY100 ProgrammingError Unikhetsalternativet är inte inom intervallet
HY101 ProgrammingError Precisionsalternativet är inte inom intervallet
HY103 ProgrammingError Ogiltig återvinningskod
HY104 ProgrammingError Ogiltig precision eller skalvärde
HY105 ProgrammingError Ogiltig parametertyp
HY106 ProgrammingError Hämta-typ utanför räckvidd
HY107 ProgrammingError Radvärde utanför räckvidden
HY109 ProgrammingError Ogiltig markörposition
HY110 ProgrammingError Ogiltig drivrutinskomplettering
HY111 ProgrammingError Ogiltigt bokmärkesvärde
HYC00 NotSupportedError Valfri funktion har inte implementerats
HYT00 OperationalError Tidsgränsen har upphört att gälla
HYT01 OperationalError Tidsgränsen för anslutningen gick ut

Klass IM - Drivrutinshanterarfelet

SQLSTATE Exception Beskrivning
IM001 InterfaceError Drivrutinen stöder inte den här funktionen
IM002 InterfaceError Datakällans namn ej hittat
IM003 InterfaceError Angiven drivrutin kunde inte laddas
IM004 InterfaceError Drivrutinens SQLAllocHandle på SQL_HANDLE_ENV misslyckades
IM005 InterfaceError Drivrutinens SQLAllocHandle på SQL_HANDLE_DBC misslyckades
IM006 InterfaceError Drivrutinens SQLSetConnectAttr misslyckades
IM007 InterfaceError Ingen datakälla eller drivrutin specificerad
IM008 InterfaceError Dialogen misslyckades
IM009 InterfaceError Kan inte ladda översättnings-DLL
IM010 InterfaceError Datakällans namn är för långt
IM011 InterfaceError Förarnamnet är för långt
IM012 InterfaceError DRIVER nyckelordssyntaxfel
IM014 InterfaceError Ogiltigt DSN
IM015 InterfaceError Korrupt fildatakälla

Vanliga SQL Server-felnummer

Utöver SQLSTATE tillhandahåller SQL Server inbyggda felnummer inom parentes. Det här är de fel du mest sannolikt kommer att stöta på i applikationskoden. Bygg omprövningslogik kring fel 1205 (deadlock) och tillfälliga anslutningsfel (se Retry-logik).

Error Meddelandemönster Upplösning
208 Ogiltigt objektnamn Verifiera att tabellen eller vyn finns och kontrollera schema-kvalificering.
547 Begränsningsfel En främmande nyckel eller kontrollbegränsning misslyckades.
2627 Unik begränsningsöverträdelse Ett duplicert nyckelvärde lades in.
2601 Unik indexöverträdelse En dubblettnyckel finns i indexet.
4060 Kan inte öppna databasen Databasen existerar inte eller så nekas åtkomst.
18456 Inloggningen misslyckades Autentiseringsfel. Kontrollera legitimationer.
1205 Offer för dödläge Transaktionen återställdes. Försök att utföra åtgärden igen.

Snabb referens från symtom till undantag

Använd denna tabell för att kartlägga vanliga symtom till den undantagstyp du bör fånga:

Symptom Exception Sannolik orsak
"Inloggning misslyckades för användaren" OperationalError Felaktiga inloggningsuppgifter eller användaren inte mappad till databasen.
"Klient kan inte upprätta anslutning" OperationalError Servern är oåtkomlig, brandvägg eller DNS-problem.
"Timeout har gått ut" OperationalError Fråga eller anslutningstimeout. Öka timeout eller optimera frågan.
"Ogiltigt objektnamn" ProgrammingError Tabellen finns inte eller schemat specificeras inte.
"Felaktig syntax" ProgrammingError SQL-syntaxfel. Testfråga i SSMS.
"Fel antal parametrar" ProgrammingError Parameterantalet stämmer inte överens med platshållare.
"Brott mot PRIMÄRNYCKEL" IntegrityError Duplicerad nyckel. Använd MERGE eller kontrollera innan du sätter in.
"Brott mot FRÄMMANDE NYCKEL" IntegrityError Referensrad finns inte. Sätt in föräldern först.
"Transaktionen var låst" OperationalError (fel 1205) Lås konkurrensen. Implementera logik för återförsök.
"Sträng- eller binärdata skulle trunkeras" DataError Värdet överstiger kolumnlängden. Kontrollera data eller öka kolumnstorleken.
"Ombyggnaden misslyckades" DataError Typmatchningsfel. Använd rätt Python-typ för kolumnen.
"Okänt nyckelord" ConnectionStringParseError Stavfel i reťazec pripojenia-nyckelordet.
"callproc stöds inte" NotSupportedError Använd cursor.execute("EXECUTE ...") i stället.

Metodtips

  • Fånga specifika undantag innan generella . Ordna från mest specifika (IntegrityError) till minst specifika (Error).
  • Hantera alltid IntegrityError för datamodifieringsoperationer. Begränsningsbrott förväntas vid normal drift (till exempel en användare som försöker skapa ett duplicert användarnamn).
  • Logga hela felkontexten för felsökning. Undantaget exponerar driver_error (stabil, SQLSTATE-härledd text) och ddbc_error (server-side message). Logga båda; klassificera på driver_error.
  • Implementera återförsökslogik för tillfälliga fel (anslutningsfel, deadlocks). Se Ompröva logik.
  • Använd rollback() i undantagshanterare för att rensa upp misslyckade transaktioner. Utan explicit återställning förblir anslutningen i ett misslyckat transaktionstillstånd.