Il driver mssql-python definisce una gerarchia standard di eccezioni, schemi comuni di gestione degli errori e mappature di codice SQLSTATE per SQL Server e Azure SQL.
Gerarchia delle eccezioni
Il driver mssql-python segue la gerarchia delle eccezioni DB-API 2.0 (PEP 249):
Exception (builtins)
├── Warning
└── Error
├── InterfaceError
└── DatabaseError
├── DataError
├── OperationalError
├── IntegrityError
├── InternalError
├── ProgrammingError
└── NotSupportedError
ConnectionStringParseError (standalone, not part of hierarchy)
Descrizioni delle eccezioni
Individua l'eccezione più specifica che si adatta alla tua situazione. Ad esempio, per le IntegrityError violazioni dei vincoli su INSERT/UPDATE operations e ProgrammingError per problemi di sintassi SQL durante lo sviluppo. Prendi la classe base Error solo come riserva.
| Eccezione |
Quando generato |
Warning |
Avvertenze non fatali dal database. |
Error |
Classe base per tutti gli errori del database. |
InterfaceError |
Errori legati all'interfaccia del database (driver), non al database stesso. |
DatabaseError |
Errori legati al database. |
DataError |
Errori dovuti a problemi con i dati elaborati (divisione per zero, valore fuori intervallo). |
OperationalError |
Errori legati all'operazione del database (connessione persa, allocazione della memoria, errori di transazione). |
IntegrityError |
Errori quando l'integrità del database è interessata (violazione della chiave esterna, vincolo unico). |
InternalError |
Errori interni al database (cursore non valido, transazione fuori sincrono). |
ProgrammingError |
Errori di programmazione (errori di sintassi, tabella non trovata, numero sbagliato di parametri). |
NotSupportedError |
Funzionalità non supportata dal database o dal driver. |
ConnectionStringParseError |
Sintassi di stringa di connessione invalida o parole chiave sconosciute. |
Gestione di base degli errori
Usa i blocchi try-except per gestire errori nel database:
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()
Eccezioni di accesso tramite la connessione
Puoi individuare eccezioni tramite l'istanza di connessione:
try:
cursor.execute("INVALID SQL")
except conn.ProgrammingError as e:
print(f"Caught via connection: {e}")
Struttura del messaggio di errore
Gli oggetti eccezione mssql-python espongono tre attributi che provengono dalla classe base delException driver:
| Attribute |
Source |
Descrizione |
driver_error |
Driver Python |
Il testo inglese standardizzato scelto dallo SQLSTATE restituì da ODBC (ad esempio, "Communication link failure", "Invalid authorization specification", "Syntax error or access violation"). Stabile tra le uscite; sicuro da abbinare con substringhe. |
ddbc_error |
Connettività Diretta con il Database (DDBC) |
Il messaggio lato server, tipicamente preceduto da [Microsoft][SQL Server]. Il formato non è un contratto stabile. |
message |
Composto |
f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". Questo è ciò che str(exc) ritorna. |
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: ...
Il numero di errore del motore SQL Server (come 208 o 40501) non è esposto come attributo e non è incorporato in modo affidabile in nessuna delle due stringhe. Classifica gli errori per sottoclasse eccezione più driver_error testo. Per il throttling di Azure SQL, vedi Retry logic.
Classificazione SQLSTATE
mssql-python utilizza lo stato SQLSTATE restituito da ODBC per scegliere sia la sottoclasse eccezione Python sia il driver_error testo. La mappatura completa di SQLSTATE → eccezioni è presente exceptions.py nel driver source. La sezione successiva elenca gli stati SQL che appaiono più spesso con SQL Server e Azure SQL.
Errori di connessione
I guasti di connessione da mssql_python.connect() raise mssql_python.OperationalError, identici ad altri guasti di connettività:
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"
Errori della stringa di connessione
Gli errori di parsing delle stringhe di connessione aumentano 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'
Riferimento al codice SQLSTATE
I codici SQLSTATE sono codici di cinque caratteri che identificano le condizioni di errore. I primi due caratteri indicano la classe, e gli ultimi tre la sottoclasse. Raramente è necessario ispezionare direttamente questi codici. Invece, individua il tipo di eccezione Python appropriato (indicato nella colonna "Eccezione"). Usa i codici SQLSTATE quando devi distinguere tra specifiche condizioni di errore all'interno dello stesso tipo di eccezione, ad esempio per differenziare un deadlock (40001) da un guasto generale della connessione (08S01).
Classe 00 - Completamento con successo
| SQLSTATE |
Eccezione |
Descrizione |
| 00000 |
None |
Success |
Classe 01 - Avviso
| SQLSTATE |
Eccezione |
Descrizione |
| 01000 |
Warning |
Avviso generale |
| 01001 |
Warning |
Conflitto dell'operazione di cursore |
| 01002 |
Warning |
Errore di disconnessione |
| 01003 |
DataError |
Valore NULL eliminato nella funzione set |
| 01004 |
DataError |
Dati stringa, troncamento destro |
| 01006 |
Warning |
Privilegio non revocato |
| 01007 |
Warning |
Privilegio non concesso |
| 01S00 |
Warning |
Attributo di stringa di connessione non valido |
| 01S01 |
Warning |
Errore in riga |
| 01S02 |
Warning |
Valore dell'opzione modificato |
Classe 07 - Errore SQL dinamico
| SQLSTATE |
Eccezione |
Descrizione |
| 07001 |
ProgrammingError |
Numero sbagliato di parametri |
| 07002 |
ProgrammingError |
Campo COUNT errato |
| 07005 |
ProgrammingError |
Istruzione preparata, non specifica del cursore |
| 07006 |
ProgrammingError |
Violazione dell'attributo del tipo di dati con restrizioni |
| 07009 |
ProgrammingError |
Indice descrittore non valido |
| 07S01 |
ProgrammingError |
Uso non valido del parametro predefinito |
Classe 08 - Eccezione per connessione
| SQLSTATE |
Eccezione |
Descrizione |
| 08001 |
ErroreOperativo |
Il client non è in grado di stabilire la connessione |
| 08002 |
ErroreOperativo |
Nome connessione in uso |
| 08003 |
ErroreOperativo |
La connessione non esiste |
| 08004 |
ErroreOperativo |
Il server ha rifiutato la connessione |
| 08007 |
ErroreOperativo |
Guasto della connessione durante la transazione |
| 08S01 |
ErroreOperativo |
Errore del collegamento di comunicazione |
Classe 21 - Violazione della cardinalità
| SQLSTATE |
Eccezione |
Descrizione |
| 21S01 |
ProgrammingError |
L'elenco di valori di inserimento non corrisponde all'elenco di colonne |
| 21S02 |
ProgrammingError |
Il grado di tabella derivata non corrisponde all'elenco di colonne |
Classe 22 - Eccezione dati
| SQLSTATE |
Eccezione |
Descrizione |
| 22001 |
DataError |
Dati stringa, troncamento destro |
| 22002 |
DataError |
Variabile indicatore obbligatoria ma non fornita |
| 22003 |
DataError |
Valore numerico non compreso nell'intervallo |
| 22007 |
DataError |
Formato datetime non valido |
| 22008 |
DataError |
Overflow del campo Datetime |
| 22012 |
DataError |
Divisione per zero |
| 22015 |
DataError |
Overflow del campo intervallo |
| 22018 |
DataError |
Valore carattere non valido per la specifica del cast |
| 22019 |
DataError |
Carattere di escape non valido |
| 22025 |
DataError |
Sequenza di escape non valida |
| 22026 |
DataError |
Lunghezza dei dati non corrispondente. |
Classe 23 - Violazione dei vincoli di integrità
| SQLSTATE |
Eccezione |
Descrizione |
| 23000 |
Errore di integrità |
Violazione dei vincoli di integrità (generale) |
Classe 24 - Stato del cursore invalido
| SQLSTATE |
Eccezione |
Descrizione |
| 24000 |
Errore Interno |
Stato del cursore non valido |
Classe 25 - Stato della transazione invalido
| SQLSTATE |
Eccezione |
Descrizione |
| 25000 |
ErroreOperativo |
Stato della transazione invalido |
| 25S01 |
ErroreOperativo |
Stato della transazione sconosciuto |
| 25S02 |
ErroreOperativo |
La transazione è ancora attiva |
| 25S03 |
ErroreOperativo |
La transazione viene annullata |
Classe 28 - Specifica di autorizzazione invalida
| SQLSTATE |
Eccezione |
Descrizione |
| 28000 |
ErroreOperativo |
Specifica di autorizzazione non valida (accesso fallito) |
Classe 34 - Nome cursore invalido
| SQLSTATE |
Eccezione |
Descrizione |
| 34000 |
ProgrammingError |
Nome di cursore non valido |
Classe 3C - Nome duplicato del cursore
| SQLSTATE |
Eccezione |
Descrizione |
| 3C000 |
ProgrammingError |
Nome cursore duplicato |
Classe 3D - Nome del catalogo non valido
| SQLSTATE |
Eccezione |
Descrizione |
| 3D000 |
ProgrammingError |
Nome catalogo non valido |
Classe 3F - Nome dello schema non valido
| SQLSTATE |
Eccezione |
Descrizione |
| 3F000 |
ProgrammingError |
Nome dello schema non valido |
Classe 40 - Rollback delle transazioni
| SQLSTATE |
Eccezione |
Descrizione |
| 40001 |
ErroreOperativo |
Guasto della serializzazione (deadlock) |
| 40002 |
ErroreOperativo |
La violazione dei vincoli di integrità ha causato un rollback |
| 40003 |
ErroreOperativo |
Completamento istruzione sconosciuto |
Classe 42 - Errore di sintassi o violazione della regola di accesso
| SQLSTATE |
Eccezione |
Descrizione |
| 42000 |
ProgrammingError |
Errore di sintassi o violazione di accesso |
| 42S01 |
ProgrammingError |
Tabella o vista di base già esistente |
| 42S02 |
ProgrammingError |
Tabella o vista di base non trovata |
| 42S11 |
ProgrammingError |
Indice già esistente |
| 42S12 |
ProgrammingError |
Indice non trovato |
| 42S21 |
ProgrammingError |
Colonna già esistente |
| 42S22 |
ProgrammingError |
Colonna non trovata |
Classe 44 - VIOLAZIONE DELL'OPZIONE CHECK
| SQLSTATE |
Eccezione |
Descrizione |
| 44000 |
Errore di integrità |
Violazione della clausola WITH CHECK OPTION |
Classe HY - condizione specifica CLI
| SQLSTATE |
Eccezione |
Descrizione |
| HY000 |
DatabaseError |
Errore generale |
| HY001 |
ErroreOperativo |
Errore di allocazione della memoria |
| HY003 |
ProgrammingError |
Tipo di buffer dell'applicazione non valido |
| HY004 |
ProgrammingError |
Tipo di dati SQL non valido |
| HY007 |
ProgrammingError |
Istruzione associata non preparata |
| HY008 |
ErroreOperativo |
Operazione annullata |
| HY009 |
ProgrammingError |
Uso non valido del puntatore Null |
| HY010 |
ProgrammingError |
Errore della sequenza di funzioni |
| HY011 |
ProgrammingError |
Impossibile impostare l'attributo ora |
| HY012 |
ProgrammingError |
Codice operativo della transazione non valido |
| HY013 |
ErroreOperativo |
Errore di gestione della memoria |
| HY014 |
ErroreOperativo |
Limite di numero di maniglie superato |
| HY015 |
ProgrammingError |
Nessun nome di cursore disponibile |
| HY016 |
ProgrammingError |
Non può modificare un descrittore di riga di implementazione |
| HY017 |
ProgrammingError |
Uso non valido dell'handle descrittore assegnato automaticamente |
| HY018 |
ErroreOperativo |
Server rifiutato richiesta di cancellazione |
| HY019 |
ProgrammingError |
Dati non caratteri e non binari inviati in pezzi |
| HY020 |
DataError |
Tentare di concatenare un valore nullo |
| HY021 |
ProgrammingError |
Informazioni incoerenti sui descrittori |
| HY024 |
ProgrammingError |
Valore dell'attributo non valido |
| HY090 |
ProgrammingError |
Lunghezza della stringa o del buffer non valida |
| HY091 |
ProgrammingError |
Identificatore del campo descrittore non valido |
| HY092 |
ProgrammingError |
Identificatore di attributo/opzione invalido |
| HY095 |
ProgrammingError |
Tipo di funzione fuori dalla portata |
| HY096 |
ProgrammingError |
Tipo di informazione non valido |
| HY097 |
ProgrammingError |
Tipo di colonna fuori dalla portata |
| HY098 |
ProgrammingError |
Tipo di mirino fuori portata |
| HY099 |
ProgrammingError |
Tipo nullabile fuori dal raggio |
| HY100 |
ProgrammingError |
Tipo di opzione di univocità non compreso nell'intervallo |
| HY101 |
ProgrammingError |
Tipo di opzione accuratezza non compreso nell'intervallo |
| HY103 |
ProgrammingError |
Codice di recupero non valido |
| HY104 |
ProgrammingError |
Precisione o valore di scala non valido |
| HY105 |
ProgrammingError |
Tipo di parametro non valido |
| HY106 |
ProgrammingError |
Tipo di ritiro fuori dal raggio |
| HY107 |
ProgrammingError |
Valore della riga fuori dal range |
| HY109 |
ProgrammingError |
Posizione del cursore non valida |
| HY110 |
ProgrammingError |
Completamento del driver non valido |
| HY111 |
ProgrammingError |
Valore del segnalibro non valido |
| HYC00 |
NotSupportedError |
Funzionalità facoltativa non implementata |
| HYT00 |
ErroreOperativo |
Timeout scaduto |
| HYT01 |
ErroreOperativo |
Il timeout della connessione è scaduto |
Classe MI - Errore del driver manager
| SQLSTATE |
Eccezione |
Descrizione |
| IM001 |
InterfaceError |
Il driver non supporta questa funzione |
| IM002 |
InterfaceError |
Nome della fonte dati non trovato |
| IM003 |
InterfaceError |
Impossibile caricare il driver specificato |
| IM004 |
InterfaceError |
SQLAllocHandle del driver su SQL_HANDLE_ENV guasto |
| IM005 |
InterfaceError |
SQLAllocHandle del driver su SQL_HANDLE_DBC fallito |
| IM006 |
InterfaceError |
Il SQLSetConnectAttr del driver è fallito |
| IM007 |
InterfaceError |
Nessuna fonte di dati o driver specificati |
| IM008 |
InterfaceError |
Dialogo fallito |
| IM009 |
InterfaceError |
Impossibile caricare la DLL di traduzione |
| IM010 |
InterfaceError |
Nome origine dati troppo lungo |
| IM011 |
InterfaceError |
Nome driver troppo lungo |
| IM012 |
InterfaceError |
Errore di sintassi delle parole chiave DRIVER |
| IM014 |
InterfaceError |
DSN non valido |
| IM015 |
InterfaceError |
Fonte di dati file corrotti |
Numeri di errore comuni di SQL Server
Oltre a SQLSTATE, SQL Server fornisce numeri di errore nativi tra parentesi. Questi sono gli errori che è più probabile che incontri nel codice applicativo. Costruire la logica di ritentazione attorno all'errore 1205 (bloccaggio) e agli errori di connessione transitoria (vedi logica di ritento).
| Error |
Modello di messaggio |
Resolution |
| 208 |
Nome di oggetto non valido |
Verifica che la tabella o la vista esistano e verifica la qualificazione dello schema. |
| 547 |
Violazione del vincolo |
Un vincolo di chiave esterna o di controllo è fallito. |
| 2627 |
Violazione unica dei vincoli |
Veniva inserito un valore chiave duplicato. |
| 2601 |
Violazione dell'indice unico |
Una chiave duplicata esiste nell'indice. |
| 4060 |
Impossibile aprire il database |
Il database non esiste o l'accesso viene negato. |
| 18456 |
Accesso non riuscito |
Errore di autenticazione. Controlla le credenziali. |
| 1205 |
Vittima di deadlock |
Verrà eseguito il rollback della transazione. Ripetere l'operazione. |
Riferimento rapido da sintomo a eccezione
Usa questa tabella per mappare i sintomi comuni al tipo di eccezione che dovresti rilevare:
| Sintomo |
Eccezione |
Causa possibile |
| "Accesso fallito per l'utente" |
OperationalError |
Credenziali sbagliate o utente non mappato al database. |
| "Cliente impossibile di stabilire un connessione" |
OperationalError |
Server non raggiungibile, firewall o problema DNS. |
| "Time out scaduto" |
OperationalError |
Time out per query o connessione. Aumenta il timeout o ottimizza la query (query off). |
| "Nome oggetto non valido" |
ProgrammingError |
La tabella non esiste o lo schema non è specificato. |
| "Sintassi errata" |
ProgrammingError |
Errore di sintassi SQL. Test query in SSMS. |
| "Numero sbagliato di parametri" |
ProgrammingError |
Il conteggio dei parametri non corrisponde ai segnaposto. |
| "Violazione della CHIAVE PRIMARIA" |
IntegrityError |
Chiave duplicata. Usa MERGE o controlla prima di inserire. |
| "Violazione della CHIAVE STRANIERA" |
IntegrityError |
La riga citata non esiste. Inserisci prima il genitore. |
| "Transazione bloccata" |
OperationalError (errore 1205) |
Contenzione per la serratura. Implementare la logica di ripetizione dei tentativi. |
| "I dati della stringa o binari verrebbero troncati" |
DataError |
Il valore supera la lunghezza della colonna. Controlla i dati o aumenta la dimensione della colonna. |
| "Conversione fallita" |
DataError |
Tipo non corrispondente. Usa il tipo corretto di Python per la colonna. |
| "Parola chiave sconosciuta" |
ConnectionStringParseError |
Errore di battitura nella parola chiave della stringa di connessione. |
| "Callproc non è supportato" |
NotSupportedError |
Utilizzare invece cursor.execute("EXECUTE ..."). |
Procedure consigliate
-
Individua eccezioni specifiche prima di quelle generiche. Ordina dal più specifico (
IntegrityError) al meno specifico (Error).
-
Gestisci sempre IntegrityError per le operazioni di modifica dei dati. Le violazioni dei vincoli sono attese nel funzionamento normale (ad esempio, un utente che cerca di creare un nome utente duplicato).
-
Registra il contesto completo dell'errore per la risoluzione dei problemi. L'eccezione espone
driver_error (testo stabile derivato da SQLSTATE) e ddbc_error (messaggio lato server). Registra entrambi; classificare su driver_error.
-
Implementa la logica di ritentativi per errori transitori (guasti di connessione, bloccamenti). Vedi Logica di ritento.
-
Usa rollback() nei gestori di eccezioni per pulire le transazioni fallite. Senza un rollback esplicito, la connessione rimane in uno stato di transazione fallita.
Contenuti correlati