Sterownik mssql-python definiuje standardową hierarchię wyjątków, typowe wzorce obsługi błędów oraz mapowania kodu SQLSTATE dla SQL Server i Azure SQL.
Hierarchia wyjątków
Sterownik mssql-python podąża za hierarchią wyjątków DB-API 2.0 (PEP 249):
Exception (builtins)
├── Warning
└── Error
├── InterfaceError
└── DatabaseError
├── DataError
├── OperationalError
├── IntegrityError
├── InternalError
├── ProgrammingError
└── NotSupportedError
ConnectionStringParseError (standalone, not part of hierarchy)
Opisy wyjątków
Złap najbardziej konkretny wyjątek, który pasuje do Twojej sytuacji. Na przykład catch IntegrityError za naruszenia ograniczeń na INSERT/UPDATE operacjach oraz ProgrammingError na problemy składniowe SQL podczas rozwoju. Złap klasę bazową Error tylko jako zapas.
| Exception |
Po podniesieniu |
Warning |
Ostrzeżenia o nieśmiertelnych zagrożeniach z bazy danych. |
Error |
Klasa bazowa dla wszystkich błędów bazy danych. |
InterfaceError |
Błędy związane z interfejsem bazy danych (sterownikiem), a nie z samą bazą danych. |
DatabaseError |
Błędy związane z bazą danych. |
DataError |
Błędy wynikające z problemów z przetwarzanymi danymi (dzielenie przez zero, wartość poza zakresem). |
OperationalError |
Błędy związane z działaniem bazy danych (utrata połączenia, przydział pamięci, błędy transakcji). |
IntegrityError |
Błędy przy naruszaniu integralności bazy danych (naruszenie klucza obcego, unikalne ograniczenie). |
InternalError |
Wewnętrzne błędy bazy danych (kursor niepoprawny, transakcja niezsynchronizowana). |
ProgrammingError |
Błędy programistyczne (błędy składniowe, tabela nie znaleziona, błędna liczba parametrów). |
NotSupportedError |
Funkcja nieobsługiwana przez bazę danych ani sterownik. |
ConnectionStringParseError |
Nieprawidłowa składnia parametry połączenia lub nieznane słowa kluczowe. |
Podstawowe zarządzanie błędami
Używaj bloków try-except do obsługi błędów bazy danych:
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()
Wyjątki dostępu przez połączenie
Możesz wychwycić wyjątki przez instancję połączenia:
try:
cursor.execute("INVALID SQL")
except conn.ProgrammingError as e:
print(f"Caught via connection: {e}")
Struktura komunikatów o błędzie
Obiekty wyjątków mssql-python ujawniają trzy atrybuty pochodzące z podstawowej klasy sterownikaException:
| Attribute |
Source |
Opis |
driver_error |
Sterownik Python |
Standaryzowany angielski tekst wybrany przez SQLSTATE zwracał z ODBC (na przykład "Communication link failure", "Invalid authorization specification", ). "Syntax error or access violation" Stabilne w różnych wydaniach; Bezpiecznie dopasowywać podciągi. |
ddbc_error |
Bezpośrednia łączność bazy danych (DDBC) |
Komunikat po stronie serwera, zazwyczaj poprzedzony przez .[Microsoft][SQL Server] Format nie jest stabilną umową. |
message |
Składający się |
f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". To właśnie wraca str(exc) . |
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: ...
Numer błędu silnika SQL Server (taki jak 208 lub 40501) nie jest ujawniany jako atrybut i nie jest niezawodnie osadzony w żadnym ze znaków znaków. Klasyfikuj błędy według podklasy wyjątku plus driver_error tekst. Aby uzyskać ograniczenie Azure SQL, zobacz Retry logic.
Klasyfikacja SQLSTATE
mssql-python wykorzystuje SQLSTATE zwracany przez ODBC do wyboru zarówno podklasy wyjątku Python, jak i driver_error tekstu. Pełne mapowanie wyjątków SQLSTATE → znajduje się exceptions.py w źródle sterownika. Następna sekcja wymienia stany SQL, które najczęściej pojawiają się w SQL Server i Azure SQL.
Błędy połączenia
Awarie połączenia z mssql_python.connect() podniesioną mssql_python.OperationalError, tak samo jak inne awarie łączności:
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"
Błędy ciągu połączenia
Błędy parsowania łańcuchów połączeń powodują 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'
Referencja kodu SQLSTATE
Kody SQLSTATE to pięcioznakowe kody identyfikujące błędy. Pierwsze dwie postacie wskazują klasę, a ostatnie trzy podklasę. Rzadko trzeba bezpośrednio sprawdzać te kody. Zamiast tego złap odpowiedni typ wyjątku w Python (wymieniony w kolumnie "Exception"). Używaj kodów SQLSTATE, gdy musisz rozróżnić konkretne błędy w obrębie tego samego typu wyjątku, na przykład aby odróżnić martwy punkt (40001) od ogólnej awarii połączenia (08S01).
Klasa 00 - Pomyślne ukończenie
| SQLSTATE |
Exception |
Opis |
| 00000 |
Żaden |
Success |
Klasa 01 - Ostrzeżenie
| SQLSTATE |
Exception |
Opis |
| 01000 |
Warning |
Ostrzeżenie ogólne |
| 01001 |
Warning |
Konflikt operacji kursora |
| 01002 |
Warning |
Błąd rozłączenia |
| 01003 |
DataError |
Wartość NULL wyeliminowana w funkcji set |
| 01004 |
DataError |
Dane ciągowe, obcinanie z prawej |
| 01006 |
Warning |
Nie odwołano uprawnień |
| 01007 |
Warning |
Nie udzielono uprawnień |
| 01S00 |
Warning |
Nieprawidłowy atrybut parametry połączenia |
| 01S01 |
Warning |
Błąd w wierszu |
| 01S02 |
Warning |
Zmieniono wartość opcji |
Klasa 07 - Dynamiczny błąd SQL
| SQLSTATE |
Exception |
Opis |
| 07001 |
ProgrammingError |
Błędna liczba parametrów |
| 07002 |
ProgrammingError |
Nieprawidłowe pole COUNT |
| 07005 |
ProgrammingError |
Przygotowane zdanie, a nie specyfikacja kursora |
| 07006 |
ProgrammingError |
Naruszenie atrybutu typu danych z ograniczeniami |
| 07009 |
ProgrammingError |
Nieprawidłowy indeks deskryptorów |
| 07S01 |
ProgrammingError |
Nieprawidłowe użycie parametru domyślnego |
Klasa 08 - Wyjątek połączenia
| SQLSTATE |
Exception |
Opis |
| 08001 |
OperationalError |
Klient nie może nawiązać połączenia |
| 08002 |
OperationalError |
Używana nazwa połączenia |
| 08003 |
OperationalError |
Połączenie nie istnieje |
| 08004 |
OperationalError |
Serwer odrzucił połączenie |
| 08007 |
OperationalError |
Awaria połączenia podczas transakcji |
| 08S01 |
OperationalError |
Błąd połączenia komunikacyjnego |
Klasa 21 - Naruszenie kardynalności
| SQLSTATE |
Exception |
Opis |
| 21S01 |
ProgrammingError |
Lista wartości nie pasuje do listy kolumn. |
| 21S02 |
ProgrammingError |
Stopień tabeli pochodnej nie jest zgodny z listą kolumn |
Klasa 22 - Wyjątek dla danych
| SQLSTATE |
Exception |
Opis |
| 22001 |
DataError |
Dane ciągowe, obcinanie z prawej |
| 22002 |
DataError |
Zmienna wskaźnika jest wymagana, ale nie jest podana |
| 22003 |
DataError |
Wartość liczbowa poza zakresem |
| 22007 |
DataError |
Nieprawidłowy format daty/godziny |
| 22008 |
DataError |
Przepełnienie pola daty/godziny |
| 22012 |
DataError |
Dzielenie według zera |
| 22015 |
DataError |
Przepełnienie pola interwału |
| 22018 |
DataError |
Nieprawidłowa wartość znaku dla specyfikacji rzutu |
| 22019 |
DataError |
Nieprawidłowy znak ucieczki |
| 22025 |
DataError |
Nieprawidłowa sekwencja ucieczki |
| 22026 |
DataError |
Dane ciągu, niezgodność długości |
Klasa 23 - Naruszenie ograniczeń integralności
| SQLSTATE |
Exception |
Opis |
| 23000 |
IntegrityError |
Naruszenie ograniczeń integralności (ogólne) |
Klasa 24 - Nieprawidłowy stan kursora
| SQLSTATE |
Exception |
Opis |
| 24000 |
Błąd Wewnętrzny |
Nieprawidłowy stan kursora |
Klasa 25 - Nieprawidłowy stan transakcji
| SQLSTATE |
Exception |
Opis |
| 25000 |
OperationalError |
Nieprawidłowy stan transakcji |
| 25S01 |
OperationalError |
Stan transakcji nieznany |
| 25S02 |
OperationalError |
Transakcja nadal jest aktywna |
| 25S03 |
OperationalError |
Transakcja jest cofana |
Klasa 28 - Nieprawidłowa specyfikacja autoryzacji
| SQLSTATE |
Exception |
Opis |
| 28000 |
OperationalError |
Nieprawidłowa specyfikacja autoryzacji (logowanie zawiodło) |
Klasa 34 - Nieprawidłowa nazwa kursora
| SQLSTATE |
Exception |
Opis |
| 34000 |
ProgrammingError |
Nieprawidłowa nazwa kursora |
Klasa 3C - Podwójna nazwa kursora
| SQLSTATE |
Exception |
Opis |
| 3C000 |
ProgrammingError |
Zduplikowana nazwa kursora |
Klasa 3D - Nieprawidłowa nazwa katalogowa
| SQLSTATE |
Exception |
Opis |
| 3D000 |
ProgrammingError |
Nieprawidłowa nazwa wykazu |
Klasa 3F - Nieprawidłowa nazwa schematu
| SQLSTATE |
Exception |
Opis |
| 3F000 |
ProgrammingError |
Nieprawidłowa nazwa schematu |
Klasa 40 - Wycofanie transakcji
| SQLSTATE |
Exception |
Opis |
| 40001 |
OperationalError |
Awaria serializacji (martwy punkt) |
| 40002 |
OperationalError |
Naruszenie ograniczeń integralności spowodowało cofnięcie |
| 40003 |
OperationalError |
Ukończenie instrukcji nieznane |
Klasa 42 - Błąd składni lub naruszenie reguły dostępu
| SQLSTATE |
Exception |
Opis |
| 42000 |
ProgrammingError |
Błąd składniowy lub naruszenie dostępu |
| 42S01 |
ProgrammingError |
Tabela podstawowa lub widok już istnieje |
| 42S02 |
ProgrammingError |
Nie można odnaleźć tabeli podstawowej lub widoku |
| 42S11 |
ProgrammingError |
Indeks już istnieje |
| 42S12 |
ProgrammingError |
Nie znaleziono indeksu |
| 42S21 |
ProgrammingError |
Kolumna już istnieje |
| 42S22 |
ProgrammingError |
Nie znaleziono kolumny |
Klasa 44 - Z OPCJĄ ODZNACZENIA naruszenie
| SQLSTATE |
Exception |
Opis |
| 44000 |
IntegrityError |
Z NARUSZENIEM OPCJI SPRAWDZANIA |
Klasa HY – Specyficzny dla CLI stan
| SQLSTATE |
Exception |
Opis |
| HY000 |
DatabaseError |
Błąd ogólny |
| HY001 |
OperationalError |
Błąd alokacji pamięci |
| HY003 |
ProgrammingError |
Nieprawidłowy typ bufora aplikacji |
| HY004 |
ProgrammingError |
Nieprawidłowy typ danych SQL |
| HY007 |
ProgrammingError |
Powiązane oświadczenie nie jest przygotowane |
| HY008 |
OperationalError |
Operacja anulowana |
| HY009 |
ProgrammingError |
Nieprawidłowe użycie wskaźnika o wartości null |
| HY010 |
ProgrammingError |
Błąd sekwencji funkcji |
| HY011 |
ProgrammingError |
Atrybut nie może być teraz ustawiony |
| HY012 |
ProgrammingError |
Nieprawidłowy kod operacji transakcyjnej |
| HY013 |
OperationalError |
Błąd zarządzania pamięcią |
| HY014 |
OperationalError |
Limit liczby przekroczonych uchwytów |
| HY015 |
ProgrammingError |
Brak nazwy kursora |
| HY016 |
ProgrammingError |
Nie można modyfikować deskryptora wiersza implementacyjnego |
| HY017 |
ProgrammingError |
Nieprawidłowe użycie automatycznie przydzielanego uchwytu deskryptorów |
| HY018 |
OperationalError |
Serwer odrzucił prośbę o anulowanie |
| HY019 |
ProgrammingError |
Dane nie-znakowe i niebinarne przesyłane w kawałkach |
| HY020 |
DataError |
Próba połączenia wartości zerowej |
| HY021 |
ProgrammingError |
Niespójne informacje o deskryptorze |
| HY024 |
ProgrammingError |
Nieprawidłowa wartość atrybutu |
| HY090 |
ProgrammingError |
Nieprawidłowa długość ciągu lub buforu |
| HY091 |
ProgrammingError |
Nieprawidłowy identyfikator pola deskryptorowego |
| HY092 |
ProgrammingError |
Nieprawidłowy identyfikator atrybutu/opcji |
| HY095 |
ProgrammingError |
Typ funkcji poza zakresem |
| HY096 |
ProgrammingError |
Nieprawidłowy typ informacji |
| HY097 |
ProgrammingError |
Typ kolumny poza zasięgiem |
| HY098 |
ProgrammingError |
Typ lunety poza zasięgiem |
| HY099 |
ProgrammingError |
Typ nullable poza zasięgiem |
| HY100 |
ProgrammingError |
Typ opcji unikatowości poza zakresem |
| HY101 |
ProgrammingError |
Typ opcji dokładności poza zakresem |
| HY103 |
ProgrammingError |
Nieprawidłowy kod odzyskiwania |
| HY104 |
ProgrammingError |
Nieprawidłowa precyzja lub wartość skali |
| HY105 |
ProgrammingError |
Nieprawidłowy typ parametru |
| HY106 |
ProgrammingError |
Typ aportowania poza zasięgiem |
| HY107 |
ProgrammingError |
Wartość wiersza poza zakresem |
| HY109 |
ProgrammingError |
Nieprawidłowa pozycja kursora |
| HY110 |
ProgrammingError |
Nieprawidłowe uzupełnienie sterownika |
| HY111 |
ProgrammingError |
Nieprawidłowa wartość zakładek |
| HYC00 |
NieSupportedError |
Opcjonalna funkcja nie zaimplementowana |
| HYT00 |
OperationalError |
Upłynął limit czasu |
| HYT01 |
OperationalError |
Upłynął limit czasu połączenia |
Klasa IM - Błąd menedżera sterownika
| SQLSTATE |
Exception |
Opis |
| IM001 |
InterfaceError |
Sterownik nie obsługuje tej funkcji |
| IM002 |
InterfaceError |
Nazwa źródła danych nie znaleziona |
| IM003 |
InterfaceError |
Określony sterownik nie mógł być załadowany |
| IM004 |
InterfaceError |
Driver's SQLAllocHandle na SQL_HANDLE_ENV nieudał się |
| IM005 |
InterfaceError |
Driver's SQLAllocHandle na SQL_HANDLE_DBC nie powiódł |
| IM006 |
InterfaceError |
SQLSetConnectAttr sterownika zawiódł |
| IM007 |
InterfaceError |
Nie podano źródła danych ani sterownika |
| IM008 |
InterfaceError |
Dialog zawiódł |
| IM009 |
InterfaceError |
Nie można załadować tłumaczenia DLL |
| IM010 |
InterfaceError |
Nazwa źródła danych jest zbyt długa |
| IM011 |
InterfaceError |
Nazwa kierowcy za długa |
| IM012 |
InterfaceError |
Błąd składni słów kluczowych DRIVER |
| IM014 |
InterfaceError |
Nieprawidłowy DSN |
| IM015 |
InterfaceError |
Uszkodzone źródło danych plików |
Typowe liczby błędów SQL Server
Poza SQLSTATE, SQL Server udostępnia natywne numery błędów w nawiasach. To są błędy, na które najczęściej natrafisz w kodzie aplikacji. Buduj logikę powtórek wokół błędu 1205 (martwy punkt) i przejściowych błędów połączenia (patrz logika powtórki).
| Błąd |
Wzorzec komunikatu |
Rozdzielczość |
| 208 |
Nieprawidłowa nazwa obiektu |
Sprawdź, czy tabela lub widok istnieje i sprawdź kwalifikację schematu. |
| 547 |
Naruszenie ograniczeń |
Klucz obcy lub ograniczenie sprawdzające zawiodło. |
| 2627 |
Naruszenie unikalnego ograniczenia |
Wstawiono duplikat wartości klucza. |
| 2601 |
Unikalne naruszenie indeksu |
W indeksie istnieje duplikat klucza. |
| 4060 |
Nie można otworzyć bazy danych |
Baza danych nie istnieje lub dostęp jest odmawiany. |
| 18456 |
Logowanie nie powiodło się |
Niepowodzenie uwierzytelniania. Sprawdź uprawnienia. |
| 1205 |
Ofiara zakleszczenia |
Transakcja została wycofana. Spróbuj ponownie wykonać operację. |
Szybkie odniesienie od objawów do wyjątków
Użyj tej tabeli, aby przypisać typowe objawy do typu wyjątku, który powinieneś wychwycić:
| Objaw |
Exception |
Prawdopodobna przyczyna |
| "Zalogowanie użytkownika się nie powiodło" |
OperationalError |
Błędne dane logowania lub użytkownik nie został przypisany do bazy danych. |
| "Klient nie może nawiązać połączenia" |
OperationalError |
Serwer niedostępny, problem z zaporą sieciową lub DNS. |
| "Timeout minął" |
OperationalError |
Zapytanie lub limit połączenia. Wydłuż czas na wydłużenie lub zoptymalizuj zapytanie. |
| "Nieprawidłowa nazwa obiektu" |
ProgrammingError |
Tabela nie istnieje ani schemat nie jest określony. |
| "Nieprawidłowa składnia" |
ProgrammingError |
Błąd składni SQL. Zapytanie testowe w SSMS. |
| "Błędna liczba parametrów" |
ProgrammingError |
Liczba parametrów nie zgadza się z tymczasowymi parametrami. |
| "Naruszenie KLUCZA GŁÓWNEGO" |
IntegrityError |
Zduplikuj klucz. Użyj MERGE lub sprawdź przed włożeniem. |
| "Naruszenie KLUCZA OBCEGO" |
IntegrityError |
Odwołany wiersz nie istnieje. Najpierw wstaw rodzica. |
| "Transakcja utknęła w martwym punkcie" |
OperationalError (błąd 1205) |
Walka o blokadę. Zaimplementuj logikę ponawiania prób. |
| "Dane ciągowe lub binarne byłyby obcięte" |
DataError |
Wartość przekracza długość kolumny. Sprawdź dane lub powiększ rubrykę. |
| "Konwersja zakończona niepowodzeniem" |
DataError |
Niezgodność typu Użyj właściwego typu Python dla kolumny. |
| "Nieznane słowo kluczowe" |
ConnectionStringParseError |
Literówka w słowie kluczowym parametry połączenia. |
| "Callproc nie jest obsługiwany" |
NotSupportedError |
Użyj cursor.execute("EXECUTE ...") zamiast tego. |
Najlepsze rozwiązania
-
Złap konkretne wyjątki przed ogólnymi. Uporządkuj od najbardziej szczegółowego (
IntegrityError) do najmniej szczegółowego (Error).
-
Zawsze obsługuj IntegrityError do operacji modyfikacji danych. Naruszenia ograniczeń są spodziewane w normalnej pracy (na przykład użytkownik próbujący utworzyć duplikatową nazwę użytkownika).
-
Zapisz pełny kontekst błędu do rozwiązywania problemów. Wyjątek eksponuje
driver_error (stabilny, pochodzący z SQLSTATE tekst) oraz ddbc_error (wiadomość po stronie serwera). Rejestruj oba; klasyfikuj na .driver_error
-
Implementuj logikę powtórek dla błędów przejściowych (awarie połączenia, martwe punkty). Zobacz logikę ponownego próbowania.
-
Użyj rollback() w obsługach wyjątków, aby usunąć nieudane transakcje. Bez wyraźnego cofnięcia połączenie pozostaje w stanie nieudanej transakcji.
Treści powiązane