Fehlerbehandlung und SQLSTATE-Codes für mssql-python

Der mssql-python-Treiber definiert eine Standard-Ausnahmehierarchie, häufige Fehlerbehandlungsmuster und SQLSTATE-Codezuordnungen für SQL Server und Azure SQL.

Ausnahmehierarchie

Der mssql-python-Treiber folgt der DB-API 2.0 (PEP 249) Ausnahmehierarchie:

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

ConnectionStringParseError (standalone, not part of hierarchy)

Ausnahmebeschreibungen

Fange die spezifischste Ausnahme, die zu deiner Situation passt. Zum Beispiel bei IntegrityError Einschränkungsverletzungen bei INSERT/UPDATE Operationen und ProgrammingError bei SQL-Syntaxproblemen während der Entwicklung erkennen. Fang die Basisklasse Error nur als Rückfall.

Exception Beim Aufheben
Warning Nicht-tödliche Warnungen aus der Datenbank.
Error Basisklasse für alle Datenbankfehler.
InterfaceError Fehler, die mit der Datenbankschnittstelle (Treiber) zusammenhängen, nicht mit der Datenbank selbst.
DatabaseError Fehler im Zusammenhang mit der Datenbank.
DataError Fehler aufgrund von Problemen mit den verarbeiteten Daten (Division durch Null, Wert außerhalb des Bereichs).
OperationalError Fehler im Zusammenhang mit dem Datenbankbetrieb (Verbindung verloren, Speicherzuweisung, Transaktionsfehler).
IntegrityError Fehler, wenn die Datenbankintegrität beeinträchtigt ist (Fremdschlüsselverletzung, eindeutige Einschränkung).
InternalError Interne Datenbankfehler (Cursor nicht gültig, Transaktion nicht synchron).
ProgrammingError Programmierfehler (Syntaxfehler, Tabelle nicht gefunden, falsche Anzahl von Parametern).
NotSupportedError Funktion wird von der Datenbank oder dem Treiber nicht unterstützt.
ConnectionStringParseError Ungültige Verbindungszeichenfolge-Syntax oder unbekannte Schlüsselwörter.

Grundlegende Fehlerbehandlung

Verwenden Sie Try-Only-Blöcke, um Datenbankfehler zu behandeln:

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()

Zugriffsausnahmen über die Verbindung

Sie können Ausnahmen über die Verbindungsinstanz erkennen:

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

Fehlermeldungsstruktur

MSSQL-Python-Ausnahmeobjekte stellen drei Attribute frei, die aus der Exception Basisklasse des Treibers stammen:

Attribute Source Beschreibung
driver_error Python-Treiber Standardisierter englischer Text, der vom SQLSTATE ausgewählt wurde, wurde von ODBC zurückgegeben (zum Beispiel "Communication link failure", "Invalid authorization specification", ). "Syntax error or access violation" Stabil über Veröffentlichungen hinweg; Sicher zum Substring-Match.
ddbc_error Direkte Datenbankverbindung (DDBC) Die serverseitige Nachricht, typischerweise mit dem Präfix .[Microsoft][SQL Server] Das Format ist kein stabiler Vertrag.
message Zusammengesetzt f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". Das ist es, was str(exc) zurückkommt.
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: ...

Die Fehlernummer der SQL Server-Engine (wie 208 oder 40501) wird nicht als Attribut angezeigt und ist in keinem der beiden Strings zuverlässig eingebettet. Klassifiziere Fehler nach Ausnahme-Unterklasse plus driver_error Text. Für Azure SQL Throttling siehe Retry Logic.

SQLSTATE-Klassifikation

mssql-python verwendet den von ODBC zurückgegebenen SQLSTATE, um sowohl die Python-Ausnahme-Unterklasse als auch den driver_error Text auszuwählen. Das vollständige SQLSTATE-→ Ausnahmemapping ist im Treibercode enthalten exceptions.py . Der nächste Abschnitt listet die SQLSTATES auf, die am häufigsten bei SQL Server und Azure SQL auftreten.

Verbindungsfehler

Verbindungsfehler von mssql_python.connect() Raise mssql_python.OperationalError, wie bei anderen Konnektivitätsfehlern:

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"

Verbindungsstring-Fehler

Fehler bei der Parsing von Verbindungsstrings führen zu 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-Codereferenz

SQLSTATE-Codes sind fünfstellige Codes, die Fehlerbedingungen identifizieren. Die ersten beiden Zeichen zeigen die Klasse an, die letzten drei die Unterklasse. Sie müssen diese Vorschriften selten direkt inspizieren. Stattdessen fangen Sie den entsprechenden Python-Ausnahmetyp ab (aufgeführt in der Spalte "Ausnahme"). Verwenden Sie SQLSTATE-Codes, wenn Sie zwischen bestimmten Fehlerzuständen innerhalb desselben Ausnahmetyps unterscheiden müssen, zum Beispiel um einen Deadlock (40001) von einem allgemeinen Verbindungsfehler (08S01) zu unterscheiden.

Baureihe 00 – Erfolgreicher Abschluss

SQLSTATE Exception Beschreibung
00000 Nichts Success

Baureihe 01 – Warnung

SQLSTATE Exception Beschreibung
01000 Warning Allgemeiner Warnhinweis
01001 Warning Cursorvorgangskonflikt
01002 Warning Trennfehler
01003 DataError NULL-Wert in set-Funktion eliminiert
01004 DataError Zeichenfolgendaten, rechtes Abschneiden
01006 Warning Nicht widerrufene Berechtigungen
01007 Warning Nicht gewährte Berechtigungen
01S00 Warning Ungültiges Verbindungszeichenfolge-Attribut
01S01 Warning Fehler in der Reihe
01S02 Warning Optionswert geändert

Klasse 07 – Dynamischer SQL-Fehler

SQLSTATE Exception Beschreibung
07001 ProgrammingError Falsche Anzahl von Parametern
07002 ProgrammingError COUNT-Feld falsch
07005 ProgrammingError Prepared Statement, keine Cursor-Spezifikation
07006 ProgrammingError Verletzung des Eingeschränkten Datentyp-Attributs
07009 ProgrammingError Ungültiger Deskriptorindex
07S01 ProgrammingError Ungültige Verwendung des Standardparameters

Baureihe 08 – Verbindungsausnahme

SQLSTATE Exception Beschreibung
08001 OperationalError Client kann keine Verbindung herstellen
08002 OperationalError Verwendeter Verbindungsname
08003 OperationalError Eine Verbindung existiert nicht
08004 OperationalError Der Server hat die Verbindung abgelehnt.
08007 OperationalError Verbindungsausfall während der Transaktion
08S01 OperationalError Kommunikationslinkfehler

Klasse 21 – Kardinalitätsverletzung

SQLSTATE Exception Beschreibung
21S01 ProgrammingError Die Liste einzufügender Werte passt nicht zur Spaltenliste.
21S02 ProgrammingError Der Grad der abgeleiteten Tabelle stimmt nicht mit der Spaltenliste überein.

Klasse 22 – Datenausnahme

SQLSTATE Exception Beschreibung
22001 DataError Zeichenfolgendaten, rechtes Abschneiden
22002 DataError Indikatorvariable erforderlich, aber nicht angegeben
22003 DataError Numerischer Wert außerhalb des Bereichs
22007 DataError Ungültiges Datetime-Format
22008 DataError Datetime-Feldüberlauf
22012 DataError Division durch Null
22015 DataError Intervallfeldüberlauf
22018 DataError Ungültiger Zeichenwert für die Umwandlungsspezifikation
22019 DataError Ungültiges Escapezeichen
22025 DataError Ungültige Escapesequenz
22026 DataError Zeichenfolgendaten, nicht übereinstimmende Länge

Klasse 23 – Verletzung der Integritätsbedingung

SQLSTATE Exception Beschreibung
23000 IntegrityError Verletzung von Integritätseinschränkungen (allgemein)

Klasse 24 – Ungültiger Cursorzustand

SQLSTATE Exception Beschreibung
24000 Interner Fehler Ungültiger Cursorstatus

Klasse 25 – Ungültiger Transaktionszustand

SQLSTATE Exception Beschreibung
25000 OperationalError Ungültiger Transaktionszustand
25S01 OperationalError Transaktionszustand unbekannt
25S02 OperationalError Die Transaktion ist noch aktiv
25S03 OperationalError Die Transaktion wird rückgängig gemacht

Klasse 28 – Ungültige Autorisierungsspezifikation

SQLSTATE Exception Beschreibung
28000 OperationalError Ungültige Autorisierungsspezifikation (Anmeldung fehlgeschlagen)

Klasse 34 – Ungültiger Cursorname

SQLSTATE Exception Beschreibung
34000 ProgrammingError Ungültiger Cursorname

Klasse 3C – Name des doppelten Cursors

SQLSTATE Exception Beschreibung
3C000 ProgrammingError Doppelter Cursorname

Klasse 3D – Ungültiger Katalogname

SQLSTATE Exception Beschreibung
3D000 ProgrammingError Ungültiger Katalogname

Klasse 3F – Ungültiger Schemaname

SQLSTATE Exception Beschreibung
3F000 ProgrammingError Ungültiger Schemaname

Klasse 40 – Transaktionsrückgang

SQLSTATE Exception Beschreibung
40001 OperationalError Serialisierungsfehler (Deadlock)
40002 OperationalError Ein Verstoß gegen die Integritätsbeschränkung führte zu einem Rollback
40003 OperationalError Abschluss der Anweisung unbekannt

Klasse 42 – Syntaxfehler oder Zugriffsregelverletzung

SQLSTATE Exception Beschreibung
42000 ProgrammingError Syntaxfehler oder Zugriffsverletzung
42S01 ProgrammingError Basistabelle oder -ansicht ist bereits vorhanden.
42S02 ProgrammingError Basistabelle oder -ansicht nicht gefunden
42S11 ProgrammingError Index ist bereits vorhanden
42S12 ProgrammingError Index nicht gefunden
42S21 ProgrammingError Spalte ist bereits vorhanden
42S22 ProgrammingError Spalte nicht gefunden

Klasse 44 – MIT CHECK-OPTION Verstoß

SQLSTATE Exception Beschreibung
44000 IntegrityError WITH CHECK OPTION-Verstoß

Klasse HY – CLI-spezifische Bedingung

SQLSTATE Exception Beschreibung
HY000 DatabaseError Allgemeiner Fehler
HY001 OperationalError Speicherzuweisungsfehler
HY003 ProgrammingError Ungültiger Anwendungspuffertyp
HY004 ProgrammingError Ungültiger SQL-Datentyp
HY007 ProgrammingError Die zugeordnete Anweisung ist nicht vorbereitet.
HY008 OperationalError Vorgang abgebrochen
HY009 ProgrammingError Ungültige Verwendung des Nullzeigers
HY010 ProgrammingError Funktionssequenzfehler
HY011 ProgrammingError Attribut kann jetzt nicht festgelegt werden
HY012 ProgrammingError Ungültiger Transaktions-Operationscode
HY013 OperationalError Speicherverwaltungsfehler
HY014 OperationalError Begrenzung für die Anzahl der überschrittenen Handles
HY015 ProgrammingError Kein Cursorname verfügbar
HY016 ProgrammingError Eine Implementierungszeilenbeschreibung kann nicht modifiziert werden
HY017 ProgrammingError Ungültige Verwendung des automatisch zugewiesenen Deskriptor-Handles
HY018 OperationalError Server hat eine Stornierungsanfrage abgelehnt
HY019 ProgrammingError Nicht-Zeichen- und nicht-binäre Daten, die in Teilen gesendet werden
HY020 DataError Versuch, einen Nullwert zu verketten
HY021 ProgrammingError Inkonsistente Deskriptorinformationen
HY024 ProgrammingError Ungültiger Attributwert
HY090 ProgrammingError Ungültige Zeichenfolgen- oder Pufferlänge
HY091 ProgrammingError Feldbekennung für ungültige Deskriptoren
HY092 ProgrammingError Ungültige Attribut-/Options-Identifikator
HY095 ProgrammingError Funktionstyp außerhalb des Bereichs
HY096 ProgrammingError Ungültiger Informationstyp
HY097 ProgrammingError Säulentyp außerhalb der Reichweite
HY098 ProgrammingError Zielfernrohrtyp außerhalb der Reichweite
HY099 ProgrammingError Nullierbarer Typ außerhalb der Reichweite
HY100 ProgrammingError Eindeutigkeitsoptionstyp außerhalb des Bereichs
HY101 ProgrammingError Genauigkeitsoptionstyp außerhalb des zulässigen Bereichs
HY103 ProgrammingError Ungültiger Abrufcode
HY104 ProgrammingError Ungültiger Genauigkeits- oder Skalierungswert
HY105 ProgrammingError Ungültiger Parametertyp
HY106 ProgrammingError Fetch-Typ außerhalb der Reichweite
HY107 ProgrammingError Zeilenwert außerhalb des Bereichs
HY109 ProgrammingError Ungültige Cursorposition
HY110 ProgrammingError Ungültige Treibervervollständigung
HY111 ProgrammingError Ungültiger Lesezeichenwert
HYC00 NotSupportedError Optionales Feature wurde nicht implementiert
HYT00 OperationalError Timeout überschritten
HYT01 OperationalError Verbindungstimeout abgelaufen

Klassen-IM – Fehler im Treibermanager

SQLSTATE Exception Beschreibung
IM001 InterfaceError Dieser Treiber unterstützt diese Funktion nicht.
IM002 InterfaceError Name der Datenquelle nicht gefunden
IM003 InterfaceError Der angegebene Treiber konnte nicht geladen werden.
IM004 InterfaceError Der SQLAllocHandle des Treibers auf SQL_HANDLE_ENV fehlgeschlagen
IM005 InterfaceError Der SQLAllocHandle des Treibers auf SQL_HANDLE_DBC fehlgeschlagen
IM006 InterfaceError Treibers SQLSetConnectAttr ist fehlgeschlagen
IM007 InterfaceError Keine Datenquelle oder Treiber spezifiziert
IM008 InterfaceError Dialog scheiterte
IM009 InterfaceError Die Übersetzungs-DLL kann nicht geladen werden.
IM010 InterfaceError Name der Datenquelle zu lang
IM011 InterfaceError Treibername zu lang
IM012 InterfaceError DRIVER-Schlüsselwortsyntaxfehler
IM014 InterfaceError Ungültige DSN
IM015 InterfaceError Beschädigte Datei-Datenquelle

Häufige SQL Server-Fehlernummern

Über SQLSTATE hinaus stellt SQL Server native Fehlernummern in Klammern bereit. Das sind die Fehler, denen Sie am wahrscheinlichsten im Anwendungscode begegnen werden. Baue die Retry-Logik um Fehler 1205 (Deadlock) und transiente Verbindungsfehler (siehe Retry-Logik).

Fehler Nachrichtenmuster Auflösung
208 Ungültiger Objektname Überprüfen Sie, ob die Tabelle oder Ansicht existiert, und überprüfen Sie die Schema-Qualifikation.
547 Einschränkungsverletzung Ein Fremdschlüssel oder eine Prüfbeschränkung ist ausgefallen.
2627 Verletzung der eindeutigen Einschränkung Ein doppelter Schlüsselwert wurde eingefügt.
2601 Eindeutige Indexverletzung Im Index existiert ein doppelter Schlüssel.
4060 Datenbank kann nicht geöffnet werden Die Datenbank existiert nicht oder der Zugriff wird verweigert.
18456 Fehler bei der Anmeldung Authentifizierungsfehler. Überprüfen Sie Ihre Zugangsdaten.
1205 Deadlock-Opfer Für die Transaktion wurde ein Rollback ausgeführt. Wiederholen Sie den Vorgang.

Schnellreferenz von Symptom zu Ausnahme

Verwenden Sie diese Tabelle, um häufige Symptome dem Ausnahmetyp zuzuordnen, den Sie fangen sollten:

Symptom Exception Wahrscheinliche Ursache
"Anmeldung fehlgeschlagen für den Benutzer" OperationalError Falsche Zugangsdaten oder Benutzer nicht der Datenbank zugeordnet.
"Kunde keine Verbindung herstellen" OperationalError Server nicht erreichbar, Firewall oder DNS-Problem.
"Timeout ist abgelaufen" OperationalError Abfrage oder Verbindungszeit. Erhöhen Sie das Timeout oder optimieren Sie die Abfrage.
"Ungültiger Objektname" ProgrammingError Es existiert keine Tabelle oder kein Schema ist nicht spezifiziert.
"Falsche Syntax" ProgrammingError SQL-Syntaxfehler. Testabfrage in SSMS.
"Falsche Anzahl von Parametern" ProgrammingError Die Parameteranzahl stimmt nicht mit Platzhaltern überein.
"Verletzung des PRIMÄRSCHLÜSSELS" IntegrityError Doppelter Schlüssel. Verwenden MERGE oder prüfen Sie es vor dem Einsetzen.
"Verletzung des FREMDSCHLÜSSELS" IntegrityError Die referenzierte Reihe existiert nicht. Zuerst Elternteil einfügen.
"Die Transaktion war blockiert" OperationalError (Fehler 1205) Der Wettbewerb wird gesichert. Implementieren Sie die Wiederholungslogik.
"String- oder Binärdaten würden abgeschnitten" DataError Der Wert übersteigt die Spaltenlänge. Überprüfen Sie die Daten oder erhöhen Sie die Spaltengröße.
"Umwandlung fehlgeschlagen" DataError Typkonflikt. Verwenden Sie den richtigen Python-Typ für die Spalte.
"Unbekanntes Schlüsselwort" ConnectionStringParseError Tippfehler im Verbindungszeichenfolge-Schlüsselwort.
"callproc wird nicht unterstützt" NotSupportedError Verwenden Sie stattdessen cursor.execute("EXECUTE ...").

Bewährte Methoden

  • Fangen Sie bestimmte Ausnahmen vor generischen Ausnahmen. Ordne von am spezifischsten (IntegrityError) bis am wenigsten spezifischen (Error).
  • Behandle IntegrityError immer für Datenmodifikationsoperationen. Einschränkungsverletzungen werden im normalen Betrieb erwartet (zum Beispiel wenn ein Benutzer versucht, einen doppelten Benutzernamen zu erstellen).
  • Protokolliere den vollständigen Fehlerkontext zur Fehlersuche. Die Ausnahme stellt driver_error (stabilen, SQLSTATE-abgeleiteten Text) und ddbc_error (serverseitige Nachricht) frei. Beide protokollieren; klassifizieren auf driver_error.
  • Retry-Logik für vorübergehende Fehler (Verbindungsausfälle, Deadlocks) implementieren. Siehe Logik für Wiederholen.
  • Verwenden Sie Rollback() in Ausnahmehandlern, um fehlgeschlagene Transaktionen zu bereinigen. Ohne explizite Rollback bleibt die Verbindung im Zustand einer fehlgeschlagenen Transaktion.