Ovladač mssql-python definuje standardní hierarchii výjimek, běžné vzory zpracování chyb a mapování kódu SQLSTATE pro SQL Server a Azure SQL.
Hierarchie výjimek
Ovladač mssql-python se řídí hierarchií výjimek DB-API 2.0 (PEP 249):
Exception (builtins)
├── Warning
└── Error
├── InterfaceError
└── DatabaseError
├── DataError
├── OperationalError
├── IntegrityError
├── InternalError
├── ProgrammingError
└── NotSupportedError
ConnectionStringParseError (standalone, not part of hierarchy)
Popisy výjimek
Chyťte tu nejkonkrétnější výjimku, která odpovídá vaší situaci. Například catch IntegrityError pro porušení omezení na INSERT/UPDATE operations a ProgrammingError pro problémy se syntaxí SQL během vývoje. Základní třídu Error chytejte jen jako záložní řešení.
| Exception |
Pokud je zvýšen |
Warning |
Varování z databáze nejsou smrtelná. |
Error |
Základní třída pro všechny chyby v databázi. |
InterfaceError |
Chyby se týkaly rozhraní databáze (ovladače), nikoli samotné databáze. |
DatabaseError |
Chyby související s databází. |
DataError |
Chyby způsobené problémy s zpracovanými daty (dělení nulou, hodnota mimo rozsah). |
OperationalError |
Chyby související s provozem databáze (ztráta spojení, alokace paměti, chyby transakcí). |
IntegrityError |
Chyby při ovlivnění integrity databáze (porušení cizího klíče, jedinečné omezení). |
InternalError |
Interní chyby v databázi (kurzor není platný, transakce není synchronizovaná). |
ProgrammingError |
Programátorské chyby (syntaxické chyby, tabulka nenalezena, nesprávný počet parametrů). |
NotSupportedError |
Funkce, kterou databáze ani ovladač nepodporují. |
ConnectionStringParseError |
Neplatná syntaxe připojovací řetězec nebo neznámá klíčová slova. |
Základní zpracování chyb
Používejte bloky try-except pro řešení chyb v databázi:
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()
Výjimky pro přístup přes spojení
Výjimky můžete zachytit přes instanci spojení:
try:
cursor.execute("INVALID SQL")
except conn.ProgrammingError as e:
print(f"Caught via connection: {e}")
Struktura chybových zpráv
Objekty výjimek mssql-python zpřístupňují tři atributy, které pocházejí ze základní třídyException ovladače:
| Attribute |
Source |
Popis |
driver_error |
Python ovladač |
Standardizovaný anglický text vybraný SQLSTATE se vrátil z ODBC (například "Communication link failure", "Invalid authorization specification", "Syntax error or access violation"). Stabilní napříč vydáním; Bezpečné pro podřetězcové párování. |
ddbc_error |
Přímé připojení k databázi (DDBC) |
Zpráva na straně serveru, obvykle s předponou [Microsoft][SQL Server]. Formát není stabilní smlouva. |
message |
Složeno |
f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". Tohle str(exc) se vrací. |
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: ...
Chybové číslo SQL Server engine (například 208 nebo 40501) není jako atribut vystaveno a není spolehlivě vloženo ani do žádného z řetězců. Klasifikujte chyby podle výjimky, podtřídy plus driver_error text. Pro Azure SQL throttling viz Retry logic.
SQLSTATE klasifikace
mssql-python používá SQLSTATE vrácený ODBC k volbě jak podtřídy Python exception, tak textudriver_error. Kompletní mapování SQLSTATE → výjimek je ve exceptions.py zdrojovém kódu ovladače. Další sekce uvádí SQLSTATE, které se nejčastěji objevují u SQL Server a Azure SQL.
Chyby připojení
Selhání spojení z mssql_python.connect() raise mssql_python.OperationalError, stejně jako u jiných selhání konektivity:
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"
Chyby spojovacích řetězců
Chyby při parsování spojovacích řetězců zvyšují 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 kódová reference
SQLSTATE kódy jsou pětiznakové kódy, které identifikují chybové stavy. První dva znaky označují třídu a poslední tři podtřídu. Tyto kódy je jen zřídka nutné přímo kontrolovat. Místo toho zachyťte příslušný typ výjimky v Python (uvedený ve sloupci "Exception"). Používejte kódy SQLSTATE, když potřebujete rozlišit mezi konkrétními chybovými podmínkami ve stejném typu výjimky, například k rozlišení zablokování (40001) od obecného selhání spojení (08S01).
Třída 00 - Úspěšné dokončení
| SQLSTATE |
Exception |
Popis |
| 00000 |
Žádný |
Success |
Třída 01 - Varování
| SQLSTATE |
Exception |
Popis |
| 01000 |
Warning |
Obecné upozornění |
| 01001 |
Warning |
Konflikt operace kurzoru |
| 01002 |
Warning |
Chyba odpojení |
| 01003 |
Chyba data |
Hodnota NULL byla eliminována ve funkci set |
| 01004 |
Chyba data |
Řetězcová data, zkrácení zprava |
| 01006 |
Warning |
Oprávnění se neodvolal |
| 01007 |
Warning |
Oprávnění se neuděluje |
| 01S00 |
Warning |
Neplatný atribut připojovací řetězec |
| 01S01 |
Warning |
Chyba v řádku |
| 01S02 |
Warning |
Změna hodnoty možnosti |
Třída 07 - Dynamická chyba SQL
| SQLSTATE |
Exception |
Popis |
| 07001 |
ProgrammingError |
Špatný počet parametrů |
| 07002 |
ProgrammingError |
Nesprávné pole COUNT |
| 07005 |
ProgrammingError |
Připravené tvrzení, nikoli specifikace kurzoru |
| 07006 |
ProgrammingError |
Porušení atributu omezeného datového typu |
| 07009 |
ProgrammingError |
Index neplatných deskriptorů |
| 07S01 |
ProgrammingError |
Neplatné použití výchozího parametru |
Třída 08 - Výjimka pro spojení
| SQLSTATE |
Exception |
Popis |
| 08001 |
OperationalError |
Klient nedokáže navázat spojení |
| 08002 |
OperationalError |
Používaný název spojení |
| 08003 |
OperationalError |
Spojení neexistuje |
| 08004 |
OperationalError |
Server spojení odmítl |
| 08007 |
OperationalError |
Selhání spojení během transakce |
| 08S01 |
OperationalError |
Selhání komunikačního propojení |
Třída 21 - Porušení kardinálnosti
| SQLSTATE |
Exception |
Popis |
| 21S01 |
ProgrammingError |
Seznam vložených hodnot neodpovídá seznamu sloupců |
| 21S02 |
ProgrammingError |
Stupeň odvozené tabulky neodpovídá seznamu sloupců |
Třída 22 - Výjimka pro data
| SQLSTATE |
Exception |
Popis |
| 22001 |
Chyba data |
Řetězcová data, zkrácení zprava |
| 22002 |
Chyba data |
Požadovaná proměnná ukazatele, ale není zadána |
| 22003 |
Chyba data |
Číselná hodnota mimo rozsah |
| 22007 |
Chyba data |
Neplatný formát data a času |
| 22008 |
Chyba data |
Přetečení pole Datetime |
| 22012 |
Chyba data |
Dělení nulou |
| 22015 |
Chyba data |
Přetečení pole intervalu |
| 22018 |
Chyba data |
Neplatná hodnota znaku pro specifikaci přetypování |
| 22019 |
Chyba data |
Neplatný řídicí znak |
| 22025 |
Chyba data |
Neplatná řídicí sekvence |
| 22026 |
Chyba data |
Řetězcová data, neshoda délky |
Třída 23 - Porušení integrity
| SQLSTATE |
Exception |
Popis |
| 23000 |
IntegrityError |
Porušení integrity (obecné) |
Třída 24 - Neplatný stav kurzoru
| SQLSTATE |
Exception |
Popis |
| 24000 |
Vnitřní chyba |
Neplatný stav kurzoru |
Třída 25 - Neplatný stav transakce
| SQLSTATE |
Exception |
Popis |
| 25000 |
OperationalError |
Neplatný stav transakce |
| 25S01 |
OperationalError |
Stav transakce neznámý |
| 25S02 |
OperationalError |
Transakce je stále aktivní |
| 25S03 |
OperationalError |
Transakce je vrácena zpět |
Třída 28 - Specifikace neplatné autorizace
| SQLSTATE |
Exception |
Popis |
| 28000 |
OperationalError |
Neplatná specifikace autorizace (přihlášení selhalo) |
Třída 34 - Neplatné jméno kurzoru
| SQLSTATE |
Exception |
Popis |
| 34000 |
ProgrammingError |
Neplatný název kurzoru |
Třída 3C - Duplikát názvu kurzoru
| SQLSTATE |
Exception |
Popis |
| 3C000 |
ProgrammingError |
Duplicitní název kurzoru |
Třída 3D - Neplatné katalogové jméno
| SQLSTATE |
Exception |
Popis |
| 3D000 |
ProgrammingError |
Neplatný název katalogu |
Třída 3F - Neplatné schématové jméno
| SQLSTATE |
Exception |
Popis |
| 3F000 |
ProgrammingError |
Neplatný název schématu |
Třída 40 - Návrat transakcí zpět
| SQLSTATE |
Exception |
Popis |
| 40001 |
OperationalError |
Selhání serializace (zablokování) |
| 40002 |
OperationalError |
Porušení integrity způsobilo návrat zpět |
| 40003 |
OperationalError |
Neznámé dokončování příkazů |
Třída 42 - Chyba syntaxe nebo porušení přístupových pravidel
| SQLSTATE |
Exception |
Popis |
| 42000 |
ProgrammingError |
Chyba syntaxe nebo porušení přístupu |
| 42S01 |
ProgrammingError |
Základní tabulka nebo zobrazení již existují. |
| 42S02 |
ProgrammingError |
Základní tabulka nebo zobrazení nebyly nalezeny. |
| 42S11 |
ProgrammingError |
Index již existuje. |
| 42S12 |
ProgrammingError |
Index nebyl nalezen. |
| 42S21 |
ProgrammingError |
Sloupec již existuje. |
| 42S22 |
ProgrammingError |
Sloupec nebyl nalezen. |
Třída 44 - S MOŽNOSTÍ ZAŠKRTNOUT porušení
| SQLSTATE |
Exception |
Popis |
| 44000 |
IntegrityError |
PORUŠENÍ FUNKCE CHECK OPTION |
Třída HY – CLI-specifická podmínka
| SQLSTATE |
Exception |
Popis |
| HY000 |
Chyba databáze |
Obecná chyba |
| HY001 |
OperationalError |
Chyba přidělení paměti |
| HY003 |
ProgrammingError |
Neplatný typ aplikačního bufferu |
| HY004 |
ProgrammingError |
Neplatný typ SQL dat |
| HY007 |
ProgrammingError |
Související prohlášení není připraveno |
| HY008 |
OperationalError |
Operace byla zrušena. |
| HY009 |
ProgrammingError |
Neplatné použití ukazatele null |
| HY010 |
ProgrammingError |
Chyba posloupnosti funkcí |
| HY011 |
ProgrammingError |
Atribut nelze nyní nastavit |
| HY012 |
ProgrammingError |
Neplatný kód operace transakce |
| HY013 |
OperationalError |
Chyba správy paměti |
| HY014 |
OperationalError |
Limit překročeného počtu rukojeti |
| HY015 |
ProgrammingError |
Není k dispozici název kurzoru |
| HY016 |
ProgrammingError |
Nelze upravovat deskriptor řádku implementace |
| HY017 |
ProgrammingError |
Neplatné použití automaticky alokovaného descriptorového handle |
| HY018 |
OperationalError |
Server odmítl žádost o zrušení |
| HY019 |
ProgrammingError |
Neznaková a nebinární data odesílaná v částech |
| HY020 |
Chyba data |
Pokus o spojení nulové hodnoty |
| HY021 |
ProgrammingError |
Nekonzistentní informace o popisech |
| HY024 |
ProgrammingError |
Neplatná hodnota atributu |
| HY090 |
ProgrammingError |
Neplatná délka řetězce nebo vyrovnávací paměti |
| HY091 |
ProgrammingError |
Neplatný identifikátor pole deskriptoru |
| HY092 |
ProgrammingError |
Neplatný identifikátor atributu/opce |
| HY095 |
ProgrammingError |
Typ funkce mimo rozsah |
| HY096 |
ProgrammingError |
Typ neplatné informace |
| HY097 |
ProgrammingError |
Typ sloupce mimo dosah |
| HY098 |
ProgrammingError |
Typ zaměřovače mimo dosah |
| HY099 |
ProgrammingError |
Nullable typ mimo dosah |
| HY100 |
ProgrammingError |
Typ možnosti jedinečnosti mimo rozsah |
| HY101 |
ProgrammingError |
Typ možnosti přesnosti mimo rozsah |
| HY103 |
ProgrammingError |
Neplatný kód pro získání |
| HY104 |
ProgrammingError |
Neplatná přesnost nebo hodnota škály |
| HY105 |
ProgrammingError |
Neplatný typ parametru |
| HY106 |
ProgrammingError |
Typ aportu mimo dosah |
| HY107 |
ProgrammingError |
Hodnota řádku mimo rozsah |
| HY109 |
ProgrammingError |
Neplatná pozice kurzoru |
| HY110 |
ProgrammingError |
Dokončení neplatného ovladače |
| HY111 |
ProgrammingError |
Neplatná hodnota záložek |
| HYC00 |
NotSupportedError |
Nepovinná funkce není implementována. |
| HYT00 |
OperationalError |
Vypršel časový limit. |
| HYT01 |
OperationalError |
Vypršel časový limit připojení |
Třída IM - Chyba správce ovladačů
| SQLSTATE |
Exception |
Popis |
| IM001 |
InterfaceError |
Ovladač tuto funkci nepodporuje. |
| IM002 |
InterfaceError |
Název zdroje dat nenalezen |
| IM003 |
InterfaceError |
Specifikovaný ovladač nemohl být načítán |
| IM004 |
InterfaceError |
Driver's SQLAllocHandle na SQL_HANDLE_ENV selhal |
| IM005 |
InterfaceError |
Driver's SQLAllocHandle on SQL_HANDLE_DBC failed |
| IM006 |
InterfaceError |
Driver SQLSetConnectAttr selhal |
| IM007 |
InterfaceError |
Není specifikován žádný zdroj dat ani ovladač |
| IM008 |
InterfaceError |
Dialog selhal |
| IM009 |
InterfaceError |
Nelze načíst překlad DLL |
| IM010 |
InterfaceError |
Název zdroje dat je příliš dlouhý |
| IM011 |
InterfaceError |
Jméno řidiče je příliš dlouhé |
| IM012 |
InterfaceError |
Chyba syntaxe klíčových slov v DRIVER |
| IM014 |
InterfaceError |
Neplatné DSN |
| IM015 |
InterfaceError |
Poškozený zdroj datových dat souboru |
Běžná čísla chyb v SQL Server
Kromě SQLSTATE poskytuje SQL Server nativní čísla chyb v závorkách. To jsou chyby, na které se nejčastěji setkáte v aplikačním kódu. Postavte logiku opakovaných pokusů kolem chyby 1205 (zablokování) a přechodných chyb připojení (viz logika opakování).
| Error |
Vzor zprávy |
Rozlišení |
| 208 |
Neplatný název objektu |
Ověřte, že tabulka nebo pohled existuje, a zkontrolujte kvalifikaci schématu. |
| 547 |
Porušení omezení |
Cizí klíč nebo kontrolní omezení selhalo. |
| 2627 |
Porušení jedinečného omezení |
Byla vložena duplicitní hodnota klíče. |
| 2601 |
Porušení jedinečného indexu |
V indexu existuje duplicitní klíč. |
| 4060 |
Nelze otevřít databázi |
Databáze neexistuje nebo je přístup odepřen. |
| 18456 |
Přihlášení se nezdařilo. |
Selhání autentizace. Zkontrolujte si přihlašovací údaje. |
| 1205 |
Oběť zablokování |
Transakce byla vrácena zpět. Zkuste operaci zopakovat. |
Rychlá referencie od symptomů k výjimkám
Použijte tuto tabulku k přiřazení běžných příznaků na typ výjimky, který byste měli zachytit:
| Příznak |
Exception |
Pravděpodobná příčina |
| "Přihlášení pro uživatele selhalo" |
OperationalError |
Špatné přihlašovací údaje nebo uživatel není přiřazen k databázi. |
| "Klient nedokáže navázat spojení" |
OperationalError |
Server nedostupný, problém s firewallem nebo DNS. |
| "Vypršel časový limit" |
OperationalError |
Dotaz nebo vypršení připojení k připojení. Zvyšte časový limit nebo optimalizujte dotazy. |
| "Neplatné jméno objektu" |
ProgrammingError |
Tabulka neexistuje ani schéma není specifikováno. |
| "Nesprávná syntaxe" |
ProgrammingError |
Chyba v syntaxi SQL. Testovací dotaz v SSMS. |
| "Špatný počet parametrů" |
ProgrammingError |
Počet parametrů neodpovídá zástupcům. |
| "Porušení PRIMÁRNÍHO KLÍČE" |
IntegrityError |
Duplikát klíče. Použijte MERGE nebo zkontrolujte před vložením. |
| "Porušení CIZÍHO KLÍČE" |
IntegrityError |
Odkazovaný řádek neexistuje. Nejprve vložte rodiče. |
| "Transakce byla zablokována" |
OperationalError (chyba 1205) |
Boj o zámky. Implementujte logiku opakování. |
| "Řetězcová nebo binární data by byla zkrácena" |
DataError |
Hodnota přesahuje délku sloupce. Zkontrolujte data nebo zvětšete velikost sloupce. |
| "Konverze selhala" |
DataError |
Neshoda typů Použijte správný typ v Python pro sloupec. |
| "Neznámé klíčové slovo" |
ConnectionStringParseError |
Překlep v klíčovém slově připojovací řetězec. |
| "Callproc není podporován" |
NotSupportedError |
Místo toho použijte cursor.execute("EXECUTE ..."). |
Osvědčené postupy
-
Chyťte konkrétní výjimky před obecnými. Pořadí od nejkonkrétnějšího (
IntegrityError) po nejméně specifické (Error).
-
Vždy zvládejte IntegrityError pro operace úpravy dat. Porušení omezení se očekává při běžném provozu (například uživatel se snaží vytvořit duplicitní uživatelské jméno).
-
Zaznamenejte celý kontext chyby pro řešení problémů. Výjimka exponuje
driver_error (stabilní, ze SQLSTATE odvozený text) a ddbc_error (zprávu na straně serveru). Zaznamenejte obojí; klasifikujte na driver_error.
-
Implementujte logiku opakování pro přechodné chyby (selhání spojení, zablokování). Viz logika opakování.
-
Použijte rollback() v obslužných obslužcích výjimek k vyčištění neúspěšných transakcí. Bez explicitního rollbacku zůstává spojení ve stavu neúspěšné transakce.
Související obsah