Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Diagnostiquez et résolvez les problèmes courants lors de l’utilisation du pilote mssql-python pour vous connecter à SQL Server, Azure SQL Database, Azure SQL Managed Instance et SQL Database dans Microsoft Fabric.
Problèmes d’installation
pip échoue à l’installation ou compile à partir du code source
Symptômes :
error: Microsoft Visual C++ 14.0 or greater is required
ERROR: Failed building wheel for mssql-python
Causes et solutions possibles :
Pas de volant préassemblé pour votre plateforme
- Vérifiez que vous utilisez une version Python prise en charge (versions 3.10 et ultérieures) et une plateforme. Voir cycle de vie du support pour la matrice de compatibilité. Mettez à jour le pip avant d’installer avec
pip install --upgrade pip. Pour les environnements d’équipe reproductibles, utilisez le flux de travail verrouillé dans les déploiements répétables ou les patrons de conteneurs dans le contenu et le développement local afin de réduire la dérive locale des machines.
- Vérifiez que vous utilisez une version Python prise en charge (versions 3.10 et ultérieures) et une plateforme. Voir cycle de vie du support pour la matrice de compatibilité. Mettez à jour le pip avant d’installer avec
Environnement virtuel non activé
- Activez d’abord votre environnement virtuel. Installer Python dans le système peut entraîner des erreurs d’autorisation ou des conflits.
python -m venv .venv .venv\Scripts\activate pip install mssql-python
-
Bibliothèques système Linux manquantes
- Le pilote nécessite un petit ensemble de bibliothèques système sous Linux. Voir Dépendances spécifiques à la plateforme pour les paquets à installer.
Installations de pilotes en conflit
Symptômes :
Erreurs d’importation ou comportements inattendus après une installation mssql-python parallèle pyodbc dans le même environnement.
Correctif :
mssql-python et pyodbc peuvent coexister. Si vous constatez des conflits, créez un environnement virtuel propre :
python -m venv .venv --clear
.venv\Scripts\activate
pip install mssql-python
Problèmes de connexion
Impossible de se connecter au serveur
Symptômes :
OperationalError: [08001] (0) Client unable to establish connection
Causes et solutions possibles :
Serveur injoignable
- Vérifiez que le nom du serveur et le port sont corrects.
- Vérifiez la connectivité réseau :
ping servernameoutelnet servername 1433. - Assurez-vous que le pare-feu autorise les connexions sortantes sur le port 1433.
SQL Server ne fonctionne pas
- Vérifiez que le service SQL Server a été lancé.
- Pour les instances nommées, vérifiez que le service SQL Server Browser fonctionne.
Règles de pare-feu Azure SQL
- Ajoutez l’IP de votre client aux règles du pare-feu Azure SQL dans le portail Azure.
- Pour Azure SQL Managed Instance, assurez-vous de vous connecter depuis un réseau autorisé.
# Test basic connectivity
import socket
try:
sock = socket.create_connection(("<server>.database.windows.net", 1433), timeout=5)
print("TCP connection successful")
sock.close()
except Exception as e:
print(f"Cannot reach server: {e}")
Échec de la connexion
Symptômes :
OperationalError: [28000] (18456) Login failed for user 'username'.
Causes et solutions possibles :
Non-correspondance du mode d’authentification
- Pour Azure SQL Database, Azure SQL Managed Instance et SQL Database dans Fabric, il faut privilégier un mode Microsoft Entra tel que
Authentication=ActiveDirectoryDefault. - Si vous utilisez intentionnellement l’authentification SQL, vérifiez que le serveur le permet et que vous utilisez le bon format de connexion pour ce point de terminaison.
- Pour Azure SQL Database, Azure SQL Managed Instance et SQL Database dans Fabric, il faut privilégier un mode Microsoft Entra tel que
Identifiants d’authentification SQL incorrects
- Vérifiez le nom d’utilisateur et le mot de passe.
- Pour Azure SQL, incluez le nom d’utilisateur complet :
username@servername.
L’utilisateur n’existe pas dans la base de données
- Vérifiez que l’utilisateur a accès à la base de données spécifiée.
- Vérifiez si la connexion est associée à un utilisateur de base de données.
Authentification non configurée
- Utilisez l’authentification Microsoft Entra (recommandée) :
Authentication=ActiveDirectoryDefault. - Si vous dépannez un SQL Server local qui devrait accepter l'authentification SQL, vérifiez que SQL Server utilise une authentification en mode mixte.
- Utilisez l’authentification Microsoft Entra (recommandée) :
Délai d’expiration de la connexion
Symptômes :
OperationalError: [HYT00] (0) Timeout expired
OperationalError: [HYT01] (0) Connection timeout expired
Causes et solutions possibles :
Le serveur répond lentement
- Augmenter le délai de connexion :
conn = mssql_python.connect(connection_string, timeout=60)Latence du réseau
- Vérifie le chemin réseau vers le serveur.
- Envisagez d’utiliser un chemin réseau plus court ou un VPN.
Serveur sous forte charge
- Essayez de vous connecter pendant les heures creuses.
- Contactez votre administrateur de base de données.
Erreurs de certificat SSL
Symptômes :
OperationalError: [08001] SSL Provider: The certificate chain was issued by an authority that is not trusted
Solutions :
Premièrement, privilégiez un certificat de confiance ou les schémas de développement local dans Conteneur et le développement local. Utilisez-les TrustServerCertificate=yes uniquement pour le développement local sur un serveur que vous contrôlez.
Pour le développement et les tests avec un certificat auto-signé :
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"TrustServerCertificate=yes;" # Don't use in production
)
Caution
TrustServerCertificate=yes est une solution de secours uniquement locale. Ne l’emportez pas dans des devcontainers partagés, des pipelines CI ou des déploiements en production. Pour des conseils plus larges, voir Chiffrement et certificats.
Pour la production, assurez-vous que les certificats appropriés sont installés et utilisez :
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"HostnameInCertificate=<server>.domain.com;"
)
Problèmes d’exécution des requêtes
Table ou objet non trouvé
Symptômes :
ProgrammingError: [42S02] (208) Invalid object name 'TableName'.
Causes et solutions possibles :
Mauvais contexte de base de données
# Ensure you're connected to the correct database cursor.execute("SELECT DB_NAME()") print(cursor.fetchone()[0])Schéma non spécifié
# Use fully qualified name cursor.execute("SELECT * FROM dbo.TableName")La table n’existe pas
# Check if table exists cursor.execute(""" SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TableName' """)
Erreur de syntaxe
Symptômes :
ProgrammingError: [42000] (102) Incorrect syntax near '...'.
Solutions :
Testez d’abord SQL dans SSMS pour vérifier la syntaxe
Vérifiez l’échappement des chaînes de caractères - utilisez des requêtes paramétrées :
# Wrong - vulnerable to syntax issues and SQL injection cursor.execute(f"SELECT * FROM Production.Product WHERE Name = '{name}'") # Correct - use parameters cursor.execute("SELECT * FROM Production.Product WHERE Name = %(name)s", {"name": name})
Erreurs de paramètres
Symptômes :
ProgrammingError: [07001] Wrong number of parameters
Solutions :
Comptez les points de placement et les paramètres – ils doivent correspondre
Choisissez le bon style de paramètres :
# Qmark style - positional cursor.execute("SELECT * FROM Production.Product WHERE ProductID = ? AND Name LIKE ?", (1, "Adjustable%")) print(cursor.fetchone()) # Pyformat style - named cursor.execute("SELECT * FROM Production.Product WHERE ProductID = %(id)s AND Name LIKE %(name)s", {"id": 1, "name": "Adjustable%"}) print(cursor.fetchone())
Problèmes de type de données
Erreurs de conversion de date et d’heure
Symptômes :
DataError: [22007] Invalid datetime format
Solutions :
Utilisez des objets datatime Python au lieu de chaînes de caractères :
from datetime import datetime
cursor.execute("CREATE TABLE #Events (EventDate DATETIME)")
# Wrong - this raises an error for invalid dates
try:
cursor.execute("INSERT INTO #Events (EventDate) VALUES (%(event_date)s)", {"event_date": "2024-13-45"})
except Exception as e:
print(f"Expected error: {e}")
# Correct - use Python datetime objects
cursor.execute("INSERT INTO #Events (EventDate) VALUES (%(event_date)s)", {"event_date": datetime(2024, 3, 15)})
cursor.execute("SELECT EventDate FROM #Events")
print(cursor.fetchone())
Problèmes de précision décimale
Symptômes :
Les chiffres apparaissent tronqués ou arrondis incorrectement.
Solutions :
Utilisation decimal.Decimal pour des valeurs numériques précises :
from decimal import Decimal
cursor.execute("CREATE TABLE #PriceDemo (ListPrice DECIMAL(10,2))")
# Preserve full precision
cursor.execute(
"INSERT INTO #PriceDemo (ListPrice) VALUES (%(list_price)s)",
{"list_price": Decimal("19.99")}
)
Problèmes d’encodage Unicode
Symptômes :
Les caractères spéciaux apparaissent brouillés ou causent des erreurs.
Solutions :
Utilisez les colonnes NVARCHAR pour les données Unicode dans votre base de données
Passez directement les chaînes - le driver gère l’encodage :
cursor.execute("CREATE TABLE #UnicodeDemo (Name NVARCHAR(50))") cursor.execute("INSERT INTO #UnicodeDemo (Name) VALUES (%(name)s)", {"name": "日本語"}) cursor.execute("SELECT Name FROM #UnicodeDemo") print(cursor.fetchone())
Problèmes de performance
Exécution lente des requêtes
Causes et solutions possibles :
Index manquants : Vérifiez le plan d’exécution des requêtes dans SSMS.
Grands ensembles de résultats : Utiliser
fetchmany()au lieu defetchall():cursor.arraysize = 1000 while True: rows = cursor.fetchmany() if not rows: break process_rows(rows)Pool de connexions désactivé : Activer le pool de connexions :
import mssql_python mssql_python.pooling(max_size=20, idle_timeout=300)
Problèmes de mémoire avec des résultats volumineux
Symptômes :
Le processus Python manque de mémoire.
Solutions :
Résultats du flux au lieu de tout charger en mémoire :
cursor.execute("SELECT * FROM LargeTable") for row in cursor: # Iterates one row at a time process_row(row)Utilisez la pagination côté serveur :
page_size = 1000 offset = 0 while True: cursor.execute( "SELECT * FROM LargeTable ORDER BY ID " "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", (offset, page_size) ) rows = cursor.fetchall() if not rows: break process_rows(rows) offset += page_size
Problèmes de transaction
Portée de table temporaire avec autocommit
Les tables temporaires (#tablename) créées à l’intérieur d’une transaction disparaissent lorsque celle-ci est annulée. C’est une source fréquente de confusion lorsque l’autocommit est désactivé (par défaut) :
conn = mssql_python.connect(connection_string) # autocommit=False by default
cursor = conn.cursor()
cursor.execute("CREATE TABLE #TempData (ID INT, Name NVARCHAR(50))")
cursor.execute("INSERT INTO #TempData VALUES (1, 'test')")
# If the connection rolls back (explicit or on error), #TempData disappears
conn.rollback()
# This fails: Invalid object name '#TempData'
cursor.execute("SELECT * FROM #TempData")
Correction : Commet immédiatement après avoir créé une table temporaire, ou utilise le mode autocommit :
cursor.execute("CREATE TABLE #TempData (ID INT, Name NVARCHAR(50))")
conn.commit() # Lock in the table definition
cursor.execute("INSERT INTO #TempData VALUES (1, 'test')")
conn.commit()
Les instructions DDL qui nécessitent le mode de validation automatique, telles que CREATE DATABASE, échouent dans une transaction ouverte. Définissez l’autocommit avant de les exécuter :
conn.autocommit = True
cursor.execute("CREATE DATABASE TestDB")
conn.autocommit = False
Transaction non engagée
Symptômes :
Les changements de données ne persistent pas après la fermeture de la connexion.
Solution:
Avec autocommit=False (par défaut), vous devez appeler commit():
cursor.execute("CREATE TABLE #Products (Name NVARCHAR(100))")
cursor.execute("INSERT INTO #Products (Name) VALUES (%(name)s)", {"name": "Widget"})
conn.commit() # Don't forget this!
Ou utilisez le mode d’engagement automatique :
conn = mssql_python.connect(connection_string, autocommit=True)
Erreurs d’interblocage
Symptômes :
OperationalError: [40001] (1205) Transaction ... was deadlocked on lock resources with another process
Solution:
La logique de réessai (voir logique de réessayage) gère l’échec immédiat, mais des blocages récurrents indiquent un problème de conception. Pour résoudre la cause profonde, capturez le graphique de blocage et analysez quelles instructions et types de verrous sont impliqués. Les solutions courantes incluent la réorganisation des opérations afin que les transactions concurrentes acquièrent des verrous dans la même séquence, la réduction de l’étendue des transactions et l’ajout d’indices appropriés pour diminuer la durée de verrouillage.
Pour un guide complet de l’analyse des blocages, consultez le guide des blocages. Si vous utilisez Azure SQL Database, consultez Analyser et prévenir les blocages.
Problèmes de chargement en masse
Violations de contraintes lors d’une copie en bloc
Symptômes :
RuntimeError: CHECK constraint ... Conflict occurred in database ...
RuntimeError: Cannot insert duplicate key ... violation of PRIMARY KEY constraint
Cause :
Les données de votre lot violent les contraintes de la table (clé primaire, unique, CHECK ou clé étrangère).
Correctif :
Validez les données avant de charger. Pour les grands ensembles de données, chargez-les d’abord dans une table intermédiaire, puis fusionnez-les dans la table cible :
# Load into staging, then validate
cursor.execute("CREATE TABLE ##Staging (ID INT, Name NVARCHAR(100))")
cursor.bulkcopy("##Staging", rows)
# Check for duplicates before merging
cursor.execute("""
SELECT s.ID FROM ##Staging s
INNER JOIN dbo.Target t ON s.ID = t.ID
""")
dupes = cursor.fetchall()
if dupes:
print(f"Skipping {len(dupes)} duplicate rows")
# Insert only non-duplicate rows
cursor.execute("""
INSERT INTO dbo.Target (ID, Name)
SELECT s.ID, s.Name FROM ##Staging s
WHERE NOT EXISTS (SELECT 1 FROM dbo.Target t WHERE t.ID = s.ID)
""")
conn.commit()
Pour les modèles d’upsert avec des tables intermédiaires, voir Modèles de chargement et de déplacement des données.
Erreurs de correspondance de colonnes
Symptômes :
RuntimeError: Bulk copy failure - column count mismatch
Cause :
Le nombre de colonnes dans vos données ne correspond pas au nombre de colonnes de la table cible, ou les colonnes sont dans le mauvais ordre.
Correctif :
Assurez-vous que vos données correspondent exactement au schéma de la table dans l’ordre et le nombre :
# Check the target table schema
cursor.execute("""
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable'
ORDER BY ORDINAL_POSITION
""")
for col in cursor.fetchall():
print(col)
# Match your data to the column order
rows = [
(1, "Widget", Decimal("19.99")), # Must match table column order
(2, "Gadget", Decimal("29.99")),
]
cursor.bulkcopy("dbo.MyTable", rows)
Désaccords de type lors de la copie en vrac
Symptômes :
Les données se chargent mais les valeurs sont tronquées, arrondies ou incorrectes.
Cause :
Les valeurs de Python ne correspondent pas clairement aux types de colonnes cibles. Cas courants : float valeurs chargées dans decimal des colonnes (perte de précision), ou chaînes surdimensionnées chargées dans des colonnes de longueur fixe.
Correctif :
Utilisez les bons types de Python qui correspondent à votre schéma :
from decimal import Decimal
# Use Decimal for decimal/numeric columns, not float
rows = [
(1, "Widget", Decimal("19.99")), # Correct
# (1, "Widget", 19.99), # Avoid: float loses precision
]
cursor.bulkcopy("dbo.Products", rows)
Échecs de liaison de type NumPy
Symptômes :
Les paramètres échouent silencieusement ou suscitent des erreurs de type de données lorsqu’on utilise des types numpy integer ou float.
Cause :
Les types NumPy comme numpy.int64 et numpy.int32 ne satisfont pas à isinstance(x, int) dans NumPy 2.x. L’inférence de type du conducteur ne les reconnaît pas, ce qui provoque un comportement inattendu.
Correctif :
Convertir les valeurs numpy en types natifs Python avant de lier :
import numpy as np
# Convert individual values
cursor.execute("SELECT * FROM Production.Product WHERE ProductID = %(product_id)s", {"product_id": int(np.int64(42))})
# Convert DataFrame values
for _, row in df.iterrows():
cursor.execute(
"INSERT INTO #Orders (ProductID, Qty) VALUES (%(product_id)s, %(qty)s)",
{"product_id": int(row["ProductID"]), "qty": int(row["Qty"])}
)
Pour les ensembles de données plus volumineux, utilisez plutôt les chemins d’intégration Arrow ou pandas , qui gèrent la conversion de type en interne.
Bulkcopy avec tables temporaires
Symptômes :
cursor.bulkcopy("#TempTable", data) déclenche RuntimeError: Invalid object name '#TempTable'.
Cause :
bulkcopy() Je ne peux pas résoudre les tables temporaires de session (#tablename) à cause des limitations de recherche de métadonnées. Les tables temporaires globales (##tablename) et les tables permanentes fonctionnent.
Correctif :
Utilisez une table temporaire globale ou une table de mise en scène classique :
# Global temp table (visible to all sessions, dropped when last session disconnects)
cursor.execute("CREATE TABLE ##Staging (ID INT, Name NVARCHAR(50))")
cursor.bulkcopy("##Staging", rows)
# Or use a permanent staging table
cursor.execute("CREATE TABLE dbo.Staging (ID INT, Name NVARCHAR(50))")
cursor.bulkcopy("dbo.Staging", rows)
Pour de petits ensembles de données où une table temporaire de session est préférée, utilisez executemany() plutôt :
cursor.execute("CREATE TABLE #Staging (ID INT, Name NVARCHAR(50))")
cursor.executemany("INSERT INTO #Staging (ID, Name) VALUES (?, ?)", rows)
Problèmes liés aux conteneurs et à la CI
Bibliothèques système manquantes sur Linux
Symptômes :
ImportError: libltdl.so.7: cannot open shared object file: No such file or directory
ImportError: libkrb5.so.3: cannot open shared object file
Correctif :
Installez les packs système nécessaires. Les paquets diffèrent selon leur distribution :
| Distribution | Commande d'installation |
|---|---|
| Ubuntu/Debian | sudo apt-get install libltdl7 libkrb5-3 libgssapi-krb5-2 |
| Red Hat / Fedora | sudo dnf install libtool-ltdl krb5-libs |
| Alpine | apk add libltdl krb5-libs |
Pour des exemples de Dockerfile, voir Conteneur et développement local.
Erreurs SSL de macOS après installation
Symptômes :
Des erreurs liées à SSL lors de la connexion depuis macOS, en particulier sur Apple Silicon.
Correctif :
Installez OpenSSL via Homebrew et définissez les drapeaux de liaison :
brew install openssl
export LDFLAGS="-L/opt/homebrew/opt/openssl/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl/include"
Outils de diagnostic
Activer la journalisation des pilotes
Utilisez mssql_python.setup_logging() pour activer la journalisation DEBUG complète à des fins de dépannage. Toutes les opérations de pilote sont enregistrées, y compris les instructions SQL, les paramètres, les opérations ODBC internes et les changements d’état de connexion.
import mssql_python
# Enable logging to file (default)
mssql_python.setup_logging()
# Output to stdout (useful for CI/CD and containers)
mssql_python.setup_logging(output='stdout')
# Output to both file and stdout
mssql_python.setup_logging(output='both')
# Custom log file path (must use .txt, .log, or .csv extension)
mssql_python.setup_logging(log_file_path="/var/log/myapp/mssql.log")
Les fichiers journaux sont enregistrés au format CSV et font l’objet d’une rotation automatique lorsqu’ils atteignent 512 Mo, avec conservation de cinq fichiers de sauvegarde. Les données sensibles, comme les mots de passe et les jetons d’accès, sont automatiquement masquées dans la sortie des journaux.
Pour ajouter vos propres entrées de journal aux côtés des journaux des pilotes, utilisez driver_logger:
from mssql_python.logging import driver_logger
mssql_python.setup_logging()
driver_logger.debug("[App] Starting data processing")
driver_logger.error("[App] Failed to process record")
# Your entries appear in the same file with the same format
Caution
La journalisation comporte une surcharge de performance. Activez-le uniquement lors du dépannage, pas en production par défaut.
Obtenez les informations du conducteur
Récupérez la version du pilote et les détails du serveur depuis une connexion active :
import mssql_python
conn = mssql_python.connect(connection_string)
# Driver version
print(f"Version: {mssql_python.__version__}")
# Server information
print(f"Server name: {conn.getinfo(mssql_python.SQL_SERVER_NAME)}")
print(f"Database name: {conn.getinfo(mssql_python.SQL_DATABASE_NAME)}")
Vérifier l’état de la connexion
Testez si une connexion est toujours ouverte avant de tenter les opérations :
try:
cursor = conn.cursor()
cursor.execute("SELECT 1")
print("Connection is open")
except mssql_python.Error:
print("Connection is closed or broken")
Référence rapide : Erreurs courantes
| Error | SQLSTATE | Cause courante | Correctif rapide |
|---|---|---|---|
| Le client ne peut pas établir de connexion | 08001 | Serveur inaccessible | Vérifier le nom du serveur/port |
| Échec de la connexion | 28000 | Mauvais titres d’identité | Vérifier le nom d’utilisateur/mot de passe |
| Délai expiré | HYT00/HYT01 | Réseau lent | Augmenter le délai d’attente |
| Nom d’objet non valide | 42S02 | Mauvaise table/schéma | Utilisez des noms pleinement qualifiés |
| Erreur de syntaxe | 42000 | Erreur SQL | Utiliser des requêtes paramétrables |
| Violation de contrainte | 23000 | Violation FK/PK | Vérifier l’intégrité des données |
| Deadlock | 40001 | Contention de verrouillage | Réessayez, puis analysez le graphique de blocage |