Le pilote mssql-python définit une hiérarchie d’exception standard, des schémas courants de gestion des erreurs et des correspondances de code SQLSTATE pour SQL Server et Azure SQL.
Hiérarchie d’exceptions
Le pilote mssql-python suit la hiérarchie des exceptions DB-API 2.0 (PEP 249) :
Exception (builtins)
├── Warning
└── Error
├── InterfaceError
└── DatabaseError
├── DataError
├── OperationalError
├── IntegrityError
├── InternalError
├── ProgrammingError
└── NotSupportedError
ConnectionStringParseError (standalone, not part of hierarchy)
Descriptions des exceptions
Identifiez l’exception la plus spécifique qui correspond à votre situation. Par exemple, détecter IntegrityError les violations de contraintes sur INSERT/UPDATE operations, et ProgrammingError les problèmes de syntaxe SQL pendant le développement. Ne prends la classe de Error base qu’en plan B.
| Exception |
Lorsqu'il est soulevé |
Warning |
Avertissements non mortels provenant de la base de données. |
Error |
Classe de base pour toutes les erreurs de base de données. |
InterfaceError |
Des erreurs liées à l’interface de la base de données (pilote), pas à la base de données elle-même. |
DatabaseError |
Erreurs liées à la base de données. |
DataError |
Erreurs dues à des problèmes avec les données traitées (division par zéro, valeur hors plage). |
OperationalError |
Erreurs liées au fonctionnement de la base de données (perte de connexion, allocation mémoire, erreurs de transaction). |
IntegrityError |
Erreurs lorsque l’intégrité de la base de données est affectée (violation de clé étrangère, contrainte unique). |
InternalError |
Erreurs internes de base de données (curseur non valide, transaction désynchronisée). |
ProgrammingError |
Erreurs de programmation (erreurs de syntaxe, table non trouvée, mauvais nombre de paramètres). |
NotSupportedError |
Fonctionnalité non prise en charge par la base de données ou le pilote. |
ConnectionStringParseError |
Syntaxe de chaîne de connexion invalide ou mots-clés inconnus. |
Gestion des erreurs de base
Utilisez des blocs try-except pour gérer les erreurs de base de données :
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()
Accès aux exceptions via la connexion
Vous pouvez détecter des exceptions via l’instance de connexion :
try:
cursor.execute("INVALID SQL")
except conn.ProgrammingError as e:
print(f"Caught via connection: {e}")
Structure des messages d’erreur
Les objets d’exception MSSQL-Python exposent trois attributs provenant de la classe de base duException pilote :
| Caractéristique |
Source |
Description |
driver_error |
Pilote Python |
Texte anglais standardisé choisi par l’état SQLSTATE revenu d’ODBC (par exemple, "Communication link failure", "Invalid authorization specification", "Syntax error or access violation"). Stable entre les versions ; Sûr pour le substring match. |
ddbc_error |
Connectivité directe à la base de données (DDBC) |
Le message côté serveur, généralement précédé de [Microsoft][SQL Server]. Le format n’est pas un contrat stable. |
message |
Composé |
f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". C’est ce qui str(exc) revient. |
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: ...
Le numéro d'erreur du moteur SQL Server (comme 208 ou 40501) n'est pas exposé comme attribut et n'est pas intégré de manière fiable dans aucune des chaînes. Classez les erreurs par sous-classe d’exception plus driver_error le texte. Pour le throttling Azure SQL, voir Logique de réessayage.
Classification SQLSTATE
mssql-python utilise l’état SQLSTATE retourné par ODBC pour choisir à la fois la sous-classe d’exception Python et le driver_error texte. Le SQLSTATE complet → la correspondance des exceptions se trouve exceptions.py dans le code source du pilote. La section suivante énumère les SQLSTATE qui apparaissent le plus souvent avec SQL Server et Azure SQL.
Erreurs de connexion
Les défaillances de connexion dues mssql_python.connect() au relance mssql_python.OperationalError, identiques à celles des autres défaillances de connectivité :
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"
Erreurs de chaîne de connexion
Les erreurs d’analyse syntaxique de chaînes de connexion entraînent 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'
Référence du code SQLSTATE
Les codes SQLSTATE sont des codes de cinq caractères qui identifient les conditions d’erreur. Les deux premiers caractères indiquent la classe, et les trois derniers la sous-classe. Vous avez rarement besoin d’inspecter ces codes directement. À la place, sélectionnez le type d’exception Python approprié (indiqué dans la colonne « Exception »). Utilisez des codes SQLSTATE lorsque vous devez distinguer des conditions d’erreur spécifiques au sein d’un même type d’exception, par exemple pour différencier un deadlock (40001) d’une défaillance générale de connexion (08S01).
Classe 00 - Réussite
| SQLSTATE |
Exception |
Description |
| 00000 |
None |
Success |
Classe 01 - Avertissement
| SQLSTATE |
Exception |
Description |
| 01000 |
Warning |
Avertissement général |
| 01001 |
Warning |
Conflit d’opérations de curseur |
| 01002 |
Warning |
Erreur de déconnexion |
| 01003 |
DataError |
Valeur NULL éliminée dans la fonction set |
| 01004 |
DataError |
Données de chaîne, troncation droite |
| 01006 |
Warning |
Privilège non révoqué |
| 01007 |
Warning |
Privilège non accordé |
| 01S00 |
Warning |
Attribut chaîne de connexion non valide |
| 01S01 |
Warning |
Erreur en ligne |
| 01S02 |
Warning |
Valeur d’option modifiée |
Classe 07 - Erreur SQL dynamique
| SQLSTATE |
Exception |
Description |
| 07001 |
ProgrammingError |
Mauvais nombre de paramètres |
| 07002 |
ProgrammingError |
Champ COUNT incorrect |
| 07005 |
ProgrammingError |
Déclaration préparée, pas une spécification de curseur |
| 07006 |
ProgrammingError |
Violation d’attribut de type de données restreint |
| 07009 |
ProgrammingError |
Index descripteur invalide |
| 07S01 |
ProgrammingError |
Utilisation non valide du paramètre par défaut |
Classe 08 - Exception de connexion
| SQLSTATE |
Exception |
Description |
| 08001 |
ErrorOperationalError |
Le client ne peut pas établir de connexion |
| 08002 |
ErrorOperationalError |
Nom de connexion en cours d’utilisation |
| 08003 |
ErrorOperationalError |
La connexion n’existe pas |
| 08004 |
ErrorOperationalError |
Le serveur a rejeté la connexion |
| 08007 |
ErrorOperationalError |
Défaillance de la connexion pendant la transaction |
| 08S01 |
ErrorOperationalError |
Échec de la liaison de communication |
Classe 21 - Violation de cardinalité
| SQLSTATE |
Exception |
Description |
| 21S01 |
ProgrammingError |
La liste des valeurs d’insertion ne correspond pas à la liste de colonnes |
| 21S02 |
ProgrammingError |
Le degré de table dérivée ne correspond pas à la liste des colonnes |
Classe 22 - Exception de données
| SQLSTATE |
Exception |
Description |
| 22001 |
DataError |
Données de chaîne, troncation droite |
| 22002 |
DataError |
Variable d’indicateur requise, mais non fournie |
| 22003 |
DataError |
Valeur numérique hors plage |
| 22007 |
DataError |
Format datetime non valide |
| 22008 |
DataError |
Dépassement de champ Datetime |
| 22012 |
DataError |
Division par zéro |
| 22015 |
DataError |
Dépassement de champ d’intervalle |
| 22018 |
DataError |
Valeur de caractère non valide pour la spécification de cast |
| 22019 |
DataError |
Caractère d’échappement non valide |
| 22025 |
DataError |
Séquence d’échappement non valide |
| 22026 |
DataError |
Chaîne de données ou longueur non correspondante |
Classe 23 - Violation des contraintes d’intégrité
| SQLSTATE |
Exception |
Description |
| 23000 |
IntégrityError |
Violation des contraintes d’intégrité (générale) |
Classe 24 - État du curseur invalide
| SQLSTATE |
Exception |
Description |
| 24000 |
Erreur Interne |
État de curseur non valide |
Classe 25 - État de transaction invalide
| SQLSTATE |
Exception |
Description |
| 25000 |
ErrorOperationalError |
État de transaction invalide |
| 25S01 |
ErrorOperationalError |
État de la transaction inconnu |
| 25S02 |
ErrorOperationalError |
La transaction est toujours active |
| 25S03 |
ErrorOperationalError |
La transaction est annulée |
Classe 28 - Spécification d’autorisation invalide
| SQLSTATE |
Exception |
Description |
| 28000 |
ErrorOperationalError |
Spécification d’autorisation invalide (connexion échouée) |
Classe 34 - Nom de curseur invalide
| SQLSTATE |
Exception |
Description |
| 34000 |
ProgrammingError |
Nom de curseur non valide |
Classe 3C - Nom de curseur dupliqué
| SQLSTATE |
Exception |
Description |
| 3C000 |
ProgrammingError |
Nom du curseur dupliqué |
Classe 3D - Nom de catalogue invalide
| SQLSTATE |
Exception |
Description |
| 3D000 |
ProgrammingError |
Nom du catalogue non valide |
Classe 3F - Nom de schéma invalide
| SQLSTATE |
Exception |
Description |
| 3F000 |
ProgrammingError |
Nom de schéma non valide |
Classe 40 - Annulation de transaction
| SQLSTATE |
Exception |
Description |
| 40001 |
ErrorOperationalError |
Défaillance de la sérialisation (blocage) |
| 40002 |
ErrorOperationalError |
La violation de contrainte d’intégrité a causé un retour en arrière |
| 40003 |
ErrorOperationalError |
Saisie semi-automatique de l’instruction inconnue |
Classe 42 - Erreur de syntaxe ou violation de la règle d’accès
| SQLSTATE |
Exception |
Description |
| 42000 |
ProgrammingError |
Erreur de syntaxe ou violation d’accès |
| 42S01 |
ProgrammingError |
La table ou la vue de base existe déjà |
| 42S02 |
ProgrammingError |
Table de base ou vue introuvable |
| 42S11 |
ProgrammingError |
L’index existe déjà |
| 42S12 |
ProgrammingError |
Index introuvable |
| 42S21 |
ProgrammingError |
La colonne existe déjà |
| 42S22 |
ProgrammingError |
Colonne introuvable |
Classe 44 - VIOLATION DE L’OPTION DE VÉRIFICATION
| SQLSTATE |
Exception |
Description |
| 44000 |
IntégrityError |
Violation de WITH CHECK OPTION |
Classe HY - Condition spécifique à CLI
| SQLSTATE |
Exception |
Description |
| HY000 |
DatabaseError |
Erreur générale |
| HY001 |
ErrorOperationalError |
Erreur d’allocation de mémoire |
| HY003 |
ProgrammingError |
Type de mémoire tampon d’application non valide |
| HY004 |
ProgrammingError |
Type de données SQL non valide |
| HY007 |
ProgrammingError |
L’instruction associée n’est pas préparée |
| HY008 |
ErrorOperationalError |
Opération annulée |
| HY009 |
ProgrammingError |
Utilisation non valide du pointeur Null |
| HY010 |
ProgrammingError |
Erreur de séquence de fonction |
| HY011 |
ProgrammingError |
Impossible de définir l’attribut maintenant |
| HY012 |
ProgrammingError |
Code d’opération de transaction invalide |
| HY013 |
ErrorOperationalError |
Erreur de gestion de la mémoire |
| HY014 |
ErrorOperationalError |
Limite de nombre de poignées dépassées |
| HY015 |
ProgrammingError |
Aucun nom de curseur disponible |
| HY016 |
ProgrammingError |
Impossible de modifier un descripteur de ligne d’implémentation |
| HY017 |
ProgrammingError |
Utilisation invalide du descriptor automatiquement alloué |
| HY018 |
ErrorOperationalError |
Demande d’annulation du serveur refusée |
| HY019 |
ProgrammingError |
Données non caractères et non binaires envoyées en morceaux |
| HY020 |
DataError |
Tentative de concaténation d’une valeur nulle |
| HY021 |
ProgrammingError |
Informations descriptives incohérentes |
| HY024 |
ProgrammingError |
Valeur d’attribut non valide |
| HY090 |
ProgrammingError |
Longueur de la chaîne ou de la mémoire tampon non valide |
| HY091 |
ProgrammingError |
Identifiant de champ descripteur invalide |
| HY092 |
ProgrammingError |
Identifiant d’attribut/option invalide |
| HY095 |
ProgrammingError |
Type de fonction hors de portée |
| HY096 |
ProgrammingError |
Type d’information invalide |
| HY097 |
ProgrammingError |
Type de colonne hors de portée |
| HY098 |
ProgrammingError |
Type de lunette hors de portée |
| HY0999 |
ProgrammingError |
Type nullable hors de portée |
| HY100 |
ProgrammingError |
Type d’option d’unicité hors plage |
| HY101 |
ProgrammingError |
Type d’option d’exactitude hors plage |
| HY103 |
ProgrammingError |
Code de récupération invalide |
| HY104 |
ProgrammingError |
Valeur de précision ou d’échelle non valide |
| HY105 |
ProgrammingError |
Type de paramètre non valide |
| HY106 |
ProgrammingError |
Type de récupération hors de portée |
| HY107 |
ProgrammingError |
Valeur de la ligne hors de la plage |
| HY109 |
ProgrammingError |
Position du curseur non valide |
| HY110 |
ProgrammingError |
Complétion invalide du pilote |
| HY111 |
ProgrammingError |
Valeur de marque-page invalide |
| HYC00 |
NotSupportedError |
Fonctionnalité facultative non implémentée |
| HYT00 |
ErrorOperationalError |
Délai expiré |
| HYT01 |
ErrorOperationalError |
Délai d’attente de la connexion expiré |
Classe IM - Erreur du manager du pilote
| SQLSTATE |
Exception |
Description |
| IM001 |
InterfaceError |
Le pilote ne prend pas en charge cette fonction |
| IM002 |
InterfaceError |
Nom de la source de données non trouvé |
| IM003 |
InterfaceError |
Impossible de charger le pilote spécifié |
| IM004 |
InterfaceError |
SQLAllocHandle du pilote sur SQL_HANDLE_ENV a échoué |
| IM005 |
InterfaceError |
SQLAllocHandle du pilote sur SQL_HANDLE_DBC a échoué |
| IM006 |
InterfaceError |
Le SQLSetConnectAttr du pilote a échoué |
| IM007 |
InterfaceError |
Aucune source de données ni pilote spécifié |
| IM008 |
InterfaceError |
Dialogue échoué |
| IM009 |
InterfaceError |
Impossible de charger la DLL de traduction |
| IM010 |
InterfaceError |
Nom de la source de données trop long |
| IM011 |
InterfaceError |
Nom du pilote trop long |
| IM012 |
InterfaceError |
Erreur de syntaxe de mot clé DRIVER |
| IM014 |
InterfaceError |
DSN invalide |
| IM015 |
InterfaceError |
Source de données de fichier corrompue |
Numéros d’erreur courants sur SQL Server
Au-delà de SQLSTATE, SQL Server fournit des numéros d’erreur natifs entre parenthèses. Ce sont les erreurs que vous êtes le plus susceptible de rencontrer dans le code de l’application. Construire la logique de réessai autour de l’erreur 1205 (blocage) et des erreurs de connexion transitoires (voir logique de réessayage).
| Error |
Modèle de message |
Résolution |
| 208 |
Nom d’objet non valide |
Vérifiez que la table ou la vue existe et vérifiez la qualification du schéma. |
| 547 |
Violation de contrainte |
Une clé étrangère ou une contrainte de vérification a échoué. |
| 2627 |
Violation unique de contrainte |
Une valeur clé en double a été insérée. |
| 2601 |
Violation d’index unique |
Une clé en double existe dans l’index. |
| 4060 |
Impossible d’ouvrir la base de données |
La base de données n’existe pas ou l’accès est refusé. |
| 18456 |
Échec de la connexion |
Échec d’authentification. Vérifiez les diplômes. |
| 1205 |
Victime d’un interblocage |
La transaction a été restaurée. Réessayez l’opération. |
Référence rapide des symptômes à l’exception
Utilisez ce tableau pour associer les symptômes courants au type d’exception que vous devriez détecter :
| Symptôme |
Exception |
Cause la plus probable |
| « Connexion échouée pour l’utilisateur » |
OperationalError |
Mauvaises identifiantes ou utilisateur non mappé à la base de données. |
| « Client incapable d’établir la connexion » |
OperationalError |
Serveur injoignable, pare-feu ou problème DNS. |
| « Temps mort expiré » |
OperationalError |
Délai d’attente de requête ou de connexion. Augmenter le temps d’attente ou optimiser la requête. |
| « Nom de l’objet invalide » |
ProgrammingError |
La table n’existe pas et le schéma n’est pas spécifié. |
| « Syntaxe incorrecte » |
ProgrammingError |
Erreur de syntaxe SQL. Requête de test dans SSMS. |
| « Mauvais nombre de paramètres » |
ProgrammingError |
Le nombre de paramètres ne correspond pas aux réserves. |
| « Violation de la CLÉ PRIMAIRE » |
IntegrityError |
Double de la clé. Utilisez MERGE ou vérifiez avant d’insérer. |
| « Violation de CLÉ ÉTRANGÈRE » |
IntegrityError |
La ligne référencée n’existe pas. Insérez d’abord le parent. |
| « Transaction bloquée » |
OperationalError (erreur 1205) |
Contention de serrure. Implémentez la logique de nouvelle tentative. |
| « Les données de chaîne ou binaires seraient tronquées » |
DataError |
La valeur dépasse la longueur de la colonne. Vérifiez les données ou augmentez la taille des colonnes. |
| « Conversion échouée » |
DataError |
Incompatibilité de type. Utilisez le bon type Python pour la colonne. |
| « Mot-clé inconnu » |
ConnectionStringParseError |
Faute de frappe dans le mot-clé de chaîne de connexion. |
| « Callproc n’est pas pris en charge » |
NotSupportedError |
Utilisez cursor.execute("EXECUTE ...") à la place. |
Bonnes pratiques
-
Prenez les exceptions spécifiques avant les génériques. Ordre du plus spécifique (
IntegrityError) au moins spécifique (Error).
-
Gérez toujours IntegrityError pour les opérations de modification des données. Les violations de contraintes sont attendues en fonctionnement normal (par exemple, un utilisateur essayant de créer un nom d’utilisateur en double).
-
Enregistrez le contexte complet des erreurs pour le dépannage. L’exception expose
driver_error (texte stable, dérivé de SQLSTATE) et ddbc_error (message côté serveur). Enregistrez les deux ; classifier sur driver_error.
-
Implémentez une logique de réévaluation pour les erreurs transitoires (pannes de connexion, blocages). Voir logique de réessayage.
-
Utilisez rollback() dans les gestionnaires d’exceptions pour corriger les transactions ratées. Sans retour explicite, la connexion reste dans un état de transaction échouée.
Contenu connexe