Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Diagnostica e risolvi i problemi comuni quando usi il driver mssql-python per connetterti a SQL Server, database SQL di Azure, Istanza gestita di SQL di Azure e database SQL in Microsoft Fabric.
Problemi di installazione
Fallimento dell'installazione di PIP o compilazione dal sorgente
Sintomi:
error: Microsoft Visual C++ 14.0 or greater is required
ERROR: Failed building wheel for mssql-python
Possibili cause e soluzioni:
Nessun volante preassemblato per la tua piattaforma
- Controlla di avere una versione Python supportata (versioni 3.10 e successive) e una piattaforma. Vedi ciclo di vita del supporto per la matrice di compatibilità. Aggiorna pip prima di installare con
pip install --upgrade pip. Per ambienti di team ripetibili, usa il flusso di lavoro bloccato nelle implementazioni ripetibili o i pattern container nel container e nello sviluppo locale per ridurre il drift locale della macchina.
- Controlla di avere una versione Python supportata (versioni 3.10 e successive) e una piattaforma. Vedi ciclo di vita del supporto per la matrice di compatibilità. Aggiorna pip prima di installare con
Ambiente virtuale non attivato
- Attiva prima il tuo ambiente virtuale. L'installazione di Python nel sistema può causare errori di permesso o conflitti.
python -m venv .venv .venv\Scripts\activate pip install mssql-python
-
Librerie di sistema Linux mancanti
- Il driver richiede un piccolo insieme di librerie di sistema su Linux. Vedi Dipendenze specifiche della piattaforma per i pacchetti da installare.
Installazioni di driver in conflitto
Sintomi:
Errori di importazione o comportamenti imprevisti dopo aver installato mssql-python accanto pyodbc allo stesso ambiente.
Correzione :
mssql-python e pyodbc possono coesistere. Se noti conflitti, crea un ambiente virtuale pulito:
python -m venv .venv --clear
.venv\Scripts\activate
pip install mssql-python
Problemi di connessione
Impossibile connettersi al server
Sintomi:
OperationalError: [08001] (0) Client unable to establish connection
Possibili cause e soluzioni:
Server non raggiungibile
- Verifica che il nome del server e la porta siano corretti.
- Controlla la connettività di rete:
ping servernameoppuretelnet servername 1433. - Assicurati che il firewall consenta connessioni in uscita sulla porta 1433.
SQL Server non in esecuzione
- Verifica che il servizio SQL Server sia stato avviato.
- Per le istanze nominate, verifica che il servizio SQL Server Browser sia in esecuzione.
Azure SQL firewall rules
- Aggiungi l'IP del tuo client alle regole firewall Azure SQL nel portale Azure.
- Per Istanza gestita di SQL di Azure, assicurati di connetterti da una rete consentita.
# 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}")
Accesso non riuscito
Sintomi:
OperationalError: [28000] (18456) Login failed for user 'username'.
Possibili cause e soluzioni:
Disallineamento della modalità di autenticazione
- Per database SQL di Azure, Istanza gestita di SQL di Azure e SQL database in Fabric, preferisci una modalità Microsoft Entra come
Authentication=ActiveDirectoryDefault. - Se usi l'autenticazione SQL intenzionalmente, verifica che il server la consenta e che tu stia usando il formato di login corretto per quell'endpoint.
- Per database SQL di Azure, Istanza gestita di SQL di Azure e SQL database in Fabric, preferisci una modalità Microsoft Entra come
Credenziali di autenticazione SQL errate
- Verifica nome utente e password.
- Per Azure SQL, includere il nome utente completo:
username@servername.
L'utente non esiste nel database
- Verifica che l'utente abbia accesso al database specificato.
- Controlla se l'accesso è mappato a un utente del database.
Autenticazione non configurata
- Usa l'autenticazione Microsoft Entra (consigliata):
Authentication=ActiveDirectoryDefault. - Se stai facendo una risoluzione di problemi su un SQL Server locale che dovrebbe accettare l'autenticazione SQL, verifica che SQL Server utilizzi l'autenticazione in modalità mista.
- Usa l'autenticazione Microsoft Entra (consigliata):
Timeout della connessione
Sintomi:
OperationalError: [HYT00] (0) Timeout expired
OperationalError: [HYT01] (0) Connection timeout expired
Possibili cause e soluzioni:
Il server risponde lentamente
- Aumenta il timeout della connessione:
conn = mssql_python.connect(connection_string, timeout=60)Latenza di rete
- Controlla il percorso di rete verso il server.
- Considera di usare un percorso di rete più corto o una VPN.
Server sotto carico elevato
- Prova a connetterti durante le ore di punta basse.
- Contatta l'amministratore del tuo database.
Errori del certificato SSL
Sintomi:
OperationalError: [08001] SSL Provider: The certificate chain was issued by an authority that is not trusted
Soluzioni:
Innanzitutto, privilegia un certificato attendibile o le configurazioni di sviluppo locale in Container e sviluppo locale. Usalo TrustServerCertificate=yes solo per lo sviluppo locale su un server che controlli.
Per sviluppo e test con certificato autofirmato:
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"TrustServerCertificate=yes;" # Don't use in production
)
Attenzione
TrustServerCertificate=yes è una soluzione di riserva solo locale. Non portarla in devcontainer condivisi, pipeline di CI o distribuzioni in produzione. Per indicazioni più generali, vedi Crittografia e certificati.
Per la produzione, assicurarsi che siano installati i certificati adeguati e utilizzare:
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"HostnameInCertificate=<server>.domain.com;"
)
Problemi di esecuzione delle query
Tabella o oggetto non trovato
Sintomi:
ProgrammingError: [42S02] (208) Invalid object name 'TableName'.
Possibili cause e soluzioni:
Contesto sbagliato del database
# Ensure you're connected to the correct database cursor.execute("SELECT DB_NAME()") print(cursor.fetchone()[0])Schema non specificato
# Use fully qualified name cursor.execute("SELECT * FROM dbo.TableName")Il tavolo non esiste
# Check if table exists cursor.execute(""" SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TableName' """)
Errore di sintassi
Sintomi:
ProgrammingError: [42000] (102) Incorrect syntax near '...'.
Soluzioni:
Testa prima SQL in SSMS per verificare la sintassi
Controlla la fuga delle stringhe - usa query parametrizzate:
# 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})
Errori dei parametri
Sintomi:
ProgrammingError: [07001] Wrong number of parameters
Soluzioni:
Conta i segnaposto e i parametri - devono corrispondere
Scegli lo stile di parametro giusto:
# 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())
Problemi con i tipi di dati
Errori di conversione di data e ora
Sintomi:
DataError: [22007] Invalid datetime format
Soluzioni:
Usa oggetti datetime in Python invece delle stringhe:
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())
Problemi di precisione decimale
Sintomi:
I numeri appaiono troncati o arrotondati in modo errato.
Soluzioni:
Uso decimal.Decimal per valori numerici precisi:
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")}
)
Problemi di codifica Unicode
Sintomi:
I caratteri speciali appaiono distorti o causano errori.
Soluzioni:
Usa le colonne NVARCHAR per i dati Unicode nel tuo database
Passa le stringhe direttamente - il driver gestisce la codifica:
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())
Problemi di prestazioni
Esecuzione lenta delle query
Possibili cause e soluzioni:
Indici mancanti: Controlla il piano di esecuzione delle query in SSMS.
Grandi set di risultati: Usa
fetchmany()invece difetchall():cursor.arraysize = 1000 while True: rows = cursor.fetchmany() if not rows: break process_rows(rows)Pooling delle connessioni disabilitato: Abilita il pooling delle connessioni:
import mssql_python mssql_python.pooling(max_size=20, idle_timeout=300)
Problemi di memoria con risultati grandi
Sintomi:
Il processo Python esaurisce la memoria.
Soluzioni:
Risultati dello stream invece di caricare tutti in memoria:
cursor.execute("SELECT * FROM LargeTable") for row in cursor: # Iterates one row at a time process_row(row)Usa la paginazione lato server:
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
Problemi di transazione
Visibilità delle tabelle temporanee con autocommit
Le tabelle temporanee (#tablename) create all'interno di una transazione scompaiono quando viene eseguito il rollback della transazione. Questa è una fonte comune di confusione quando l'autocommit è disattivato (il valore predefinito):
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")
Correzione: Effettua il commit immediatamente dopo aver creato una tabella temporanea, oppure usa la modalità 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()
Le istruzioni DDL che richiedono la modalità autocommitto, come CREATE DATABASE, falliscono all'interno di una transazione aperta. Imposta l'autocommit prima di eseguirli:
conn.autocommit = True
cursor.execute("CREATE DATABASE TestDB")
conn.autocommit = False
Transazione non commessa
Sintomi:
I cambiamenti nei dati non persistono dopo la chiusura della connessione.
Soluzione:
Con autocommit=False (predefinito), devi chiamare 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!
Oppure usa la modalità autocommit:
conn = mssql_python.connect(connection_string, autocommit=True)
Errori di deadlock
Sintomi:
OperationalError: [40001] (1205) Transaction ... was deadlocked on lock resources with another process
Soluzione:
La logica di ritentativi (vedi logica di ritento) gestisce il guasto immediato, ma blocchi ricorrenti indicano un problema di progettazione. Per risolvere la causa all’origine del problema, acquisisci il grafico del deadlock e analizza quali istruzioni e tipi di blocco sono coinvolti. Le correzioni comuni includono operazioni di riordinazione affinché le transazioni concorrenti acquisiscano lock nella stessa sequenza, la riduzione dell'ambito delle transazioni e l'aggiunta di indici appropriati per ridurre la durata dei lock.
Per una guida completa dell'analisi degli sblocchi, consulta la guida Deadlocks. Se usi database SQL di Azure, vedi Analizza e preveni blocchi.
Problemi di carico in blocco
Violazioni dei vincoli durante la copia di massa
Sintomi:
RuntimeError: CHECK constraint ... Conflict occurred in database ...
RuntimeError: Cannot insert duplicate key ... violation of PRIMARY KEY constraint
Causa:
I dati nel tuo batch violano i vincoli delle tabelle (chiave primaria, univoca, CHECK o chiave esterna).
Correzione :
Valida i dati prima di caricarli. Per grandi dataset, carichi prima una tabella di staging, poi unisci nel target:
# 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()
Per i modelli di upsert con tabelle di staging, vedi i modelli di caricamento e spostamento dei dati.
Errori di mappatura delle colonne
Sintomi:
RuntimeError: Bulk copy failure - column count mismatch
Causa:
Il numero di colonne nei tuoi dati non corrisponde a quello della tabella di destinazione, oppure le colonne sono nell'ordine sbagliato.
Correzione :
Assicurati che i tuoi dati corrispondano esattamente allo schema della tabella per ordine e numero:
# 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)
Discorrispondenze di tipo durante la copia di massa
Sintomi:
I dati si caricano ma i valori sono troncati, arrotondati o erratati.
Causa:
I valori di Python non corrispondono nettamente ai tipi di colonne di destinazione. Casi comuni: float valori caricati nelle decimal colonne (perdita di precisione), o stringhe sovradimensionate caricate in colonne di lunghezza fissa.
Correzione :
Usa i tipi di Python corretti che corrispondono al tuo schema:
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)
Errori di binding dei tipi NumPy
Sintomi:
I parametri falliscono silenziosamente o generano errori di tipo di dato quando si usano tipi interi o in virgola mobile di NumPy.
Causa:
I tipi di NumPy come numpy.int64 e numpy.int32 non superano isinstance(x, int) in NumPy 2.x. L'inferenza di tipo del conducente non li riconosce, il che provoca comportamenti inaspettati.
Correzione :
Converti i valori numpy in tipi nativi di Python prima di binding:
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"])}
)
Per dataset più grandi, si usano invece i percorsi di integrazione Arrow o pandas , che gestiscono internamente la conversione dei tipi.
Copia di massa con tabelle temporanee
Sintomi:
cursor.bulkcopy("#TempTable", data) solleva RuntimeError: Invalid object name '#TempTable'.
Causa:
bulkcopy() Non è possibile risolvere le tabelle temporanee della sessione (#tablename) a causa delle limitazioni di ricerca dei metadati. Le tabelle temporanee globali (##tablename) e le tabelle permanenti funzionano.
Correzione :
Usa una tabella temporanea globale o una tabella di staging normale:
# 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)
Per piccoli dataset in cui si preferisce una tabella temporanea di sessione, si usa executemany() invece:
cursor.execute("CREATE TABLE #Staging (ID INT, Name NVARCHAR(50))")
cursor.executemany("INSERT INTO #Staging (ID, Name) VALUES (?, ?)", rows)
Problemi di container e CI
Librerie di sistema mancanti su Linux
Sintomi:
ImportError: libltdl.so.7: cannot open shared object file: No such file or directory
ImportError: libkrb5.so.3: cannot open shared object file
Correzione :
Installa i pacchetti di sistema richiesti. I pacchetti differiscono per distribuzione:
| Distribution | Installa comando |
|---|---|
| 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 |
Per esempi di Dockerfile, vedi Container e sviluppo locale.
Errori SSL di macOS dopo l'installazione
Sintomi:
Errori legati a SSL quando si connette da macOS, specialmente su Apple Silicon.
Correzione :
Installa OpenSSL tramite Homebrew e imposta i flag del linker:
brew install openssl
export LDFLAGS="-L/opt/homebrew/opt/openssl/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl/include"
Strumenti di diagnostica
Abilita il logging dei driver
Usa mssql_python.setup_logging() per abilitare una registrazione DEBUG completa per la diagnostica. Tutte le operazioni del driver sono registrate, inclusi istruzioni SQL, parametri, operazioni ODBC interne e cambiamenti dello stato della connessione.
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")
I file di log sono scritti in formato CSV e ruotano automaticamente a 512 MB con cinque backup. I dati sensibili come password e token di accesso vengono automaticamente sanificati nell'output del log.
Per aggiungere le tue voci di log accanto ai log del driver, usa 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
Attenzione
Il logging ha un impatto sulle prestazioni. Attivalo solo durante la risoluzione dei problemi, non in produzione di default.
Ottieni informazioni sul conducente
Recupera la versione del driver e i dettagli del server da una connessione attiva:
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)}")
Controllare lo stato della connessione
Verifica se una connessione è ancora aperta prima di tentare le operazioni:
try:
cursor = conn.cursor()
cursor.execute("SELECT 1")
print("Connection is open")
except mssql_python.Error:
print("Connection is closed or broken")
Riferimento rapido: Errori comuni
| Error | SQLSTATE | Causa comune | Correzione rapida |
|---|---|---|---|
| Il client non è in grado di stabilire la connessione | 08001 | Server non raggiungibile | Controlla nome/porta server |
| Accesso non riuscito | 28000 | Credenziali sbagliate | Verifica nome utente/password |
| Il timeout è scaduto | HYT00/HYT01 | Rete lenta | Aumenta il timeout |
| Nome di oggetto non valido | 42S02 | Tabella/schema sbagliato | Usa nomi pienamente qualificati |
| Errore di sintassi | 42000 | Errore SQL | Usare query con parametri |
| Violazione del vincolo | 23000 | Violazione FK/PK | Controlla l'integrità dei dati |
| Deadlock | 40001 | Conflitto di blocco | Riprova, poi analizza il grafico dello stallo |