إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
Diagnose and resolve common issues when using the mssql-python driver to connect to SQL Server, Azure SQL Database, Azure SQL Managed Instance, and SQL database in Microsoft Fabric.
Install issues
pip install fails or builds from source
Symptoms:
error: Microsoft Visual C++ 14.0 or greater is required
ERROR: Failed building wheel for mssql-python
Possible causes and solutions:
No prebuilt wheel for your platform
- Check that you're running a supported Python version (3.10 and later versions) and platform. See Support lifecycle for the compatibility matrix. Upgrade pip before installing with
pip install --upgrade pip. For repeatable team environments, use the locked workflow in Repeatable deployments or the container patterns in Container and local development to reduce local machine drift.
- Check that you're running a supported Python version (3.10 and later versions) and platform. See Support lifecycle for the compatibility matrix. Upgrade pip before installing with
Virtual environment not activated
- Activate your virtual environment first. Installing into the system Python can cause permission errors or conflicts.
python -m venv .venv .venv\Scripts\activate pip install mssql-python
- Missing Linux system libraries
- The driver requires a small set of system libraries on Linux. See Platform-specific dependencies for the packages to install.
Conflicting driver installations
Symptoms:
Import errors or unexpected behavior after installing mssql-python alongside pyodbc in the same environment.
Fix:
mssql-python and pyodbc can coexist. If you see conflicts, create a clean virtual environment:
python -m venv .venv --clear
.venv\Scripts\activate
pip install mssql-python
Connection issues
Unable to connect to server
Symptoms:
OperationalError: [08001] (0) Client unable to establish connection
Possible causes and solutions:
Server not reachable
- Verify the server name and port are correct.
- Check network connectivity:
ping servernameortelnet servername 1433. - Ensure firewall allows outbound connections on port 1433.
SQL Server not running
- Verify SQL Server service is started.
- For named instances, verify SQL Server Browser service is running.
Azure SQL firewall rules
- Add your client IP to the Azure SQL firewall rules in the Azure portal.
- For Azure SQL Managed Instance, ensure you're connecting from an allowed network.
# 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}")
Login failed
Symptoms:
OperationalError: [28000] (18456) Login failed for user 'username'.
Possible causes and solutions:
Authentication mode mismatch
- For Azure SQL Database, Azure SQL Managed Instance, and SQL database in Fabric, prefer a Microsoft Entra mode such as
Authentication=ActiveDirectoryDefault. - If you're using SQL authentication intentionally, verify that the server allows it and that you're using the correct login format for that endpoint.
- For Azure SQL Database, Azure SQL Managed Instance, and SQL database in Fabric, prefer a Microsoft Entra mode such as
Incorrect SQL authentication credentials
- Verify username and password.
- For Azure SQL, include the full username:
username@servername.
User doesn't exist in database
- Verify the user has access to the specified database.
- Check if the sign-in is mapped to a database user.
Authentication not configured
- Use Microsoft Entra authentication (recommended):
Authentication=ActiveDirectoryDefault. - If you're troubleshooting a local SQL Server that should accept SQL authentication, verify that SQL Server uses mixed mode authentication.
- Use Microsoft Entra authentication (recommended):
Connection timeout
Symptoms:
OperationalError: [HYT00] (0) Timeout expired
OperationalError: [HYT01] (0) Connection timeout expired
Possible causes and solutions:
Server is slow to respond
- Increase the connection timeout:
conn = mssql_python.connect(connection_string, timeout=60)Network latency
- Check network path to server.
- Consider using a shorter network path or VPN.
Server under heavy load
- Try connecting during off-peak hours.
- Contact your database administrator.
SSL certificate errors
Symptoms:
OperationalError: [08001] SSL Provider: The certificate chain was issued by an authority that is not trusted
Solutions:
First, prefer a trusted certificate or the local development patterns in Container and local development. Use TrustServerCertificate=yes only for local development against a server that you control.
For development and testing with a self-signed certificate:
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 is a local-only fallback. Don't carry it into shared devcontainers, CI pipelines, or production deployments. For broader guidance, see Encryption and certificates.
For production, ensure proper certificates are installed and use:
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"HostnameInCertificate=<server>.domain.com;"
)
Query execution issues
Table or object not found
Symptoms:
ProgrammingError: [42S02] (208) Invalid object name 'TableName'.
Possible causes and solutions:
Wrong database context
# Ensure you're connected to the correct database cursor.execute("SELECT DB_NAME()") print(cursor.fetchone()[0])Schema not specified
# Use fully qualified name cursor.execute("SELECT * FROM dbo.TableName")Table doesn't exist
# Check if table exists cursor.execute(""" SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TableName' """)
Syntax error
Symptoms:
ProgrammingError: [42000] (102) Incorrect syntax near '...'.
Solutions:
Test SQL in SSMS first to verify syntax
Check string escaping - use parameterized queries:
# 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})
Parameter errors
Symptoms:
ProgrammingError: [07001] Wrong number of parameters
Solutions:
Count placeholders and parameters - they must match
Choose the right parameter style:
# 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())
Data type issues
Datetime conversion errors
Symptoms:
DataError: [22007] Invalid datetime format
Solutions:
Use Python datetime objects instead of strings:
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())
Decimal precision issues
Symptoms:
Numbers appear truncated or rounded incorrectly.
Solutions:
Use decimal.Decimal for precise numeric values:
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")}
)
Unicode encoding issues
Symptoms:
Special characters appear garbled or cause errors.
Solutions:
Use NVARCHAR columns for Unicode data in your database
Pass strings directly - the driver handles encoding:
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())
Performance issues
Slow query execution
Possible causes and solutions:
Missing indexes: Check query execution plan in SSMS.
Large result sets: Use
fetchmany()instead offetchall():cursor.arraysize = 1000 while True: rows = cursor.fetchmany() if not rows: break process_rows(rows)Connection pooling disabled: Enable pooling:
import mssql_python mssql_python.pooling(max_size=20, idle_timeout=300)
Memory issues with large results
Symptoms:
Python process runs out of memory.
Solutions:
Stream results instead of loading all into memory:
cursor.execute("SELECT * FROM LargeTable") for row in cursor: # Iterates one row at a time process_row(row)Use server-side pagination:
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
Transaction issues
Temp table scoping with autocommit
Temp tables (#tablename) created inside a transaction disappear when the transaction is rolled back. This is a common source of confusion when autocommit is off (the default):
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")
Fix: Commit immediately after creating a temp table, or use autocommit mode:
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()
DDL statements that require autocommit mode, such as CREATE DATABASE, fail inside an open transaction. Set autocommit before running them:
conn.autocommit = True
cursor.execute("CREATE DATABASE TestDB")
conn.autocommit = False
Transaction not committed
Symptoms:
Data changes don't persist after closing connection.
Solution:
With autocommit=False (default), you must call 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!
Or use autocommit mode:
conn = mssql_python.connect(connection_string, autocommit=True)
Deadlock errors
Symptoms:
OperationalError: [40001] (1205) Transaction ... was deadlocked on lock resources with another process
Solution:
Retry logic (see Retry logic) handles the immediate failure, but recurring deadlocks indicate a design problem. To fix the root cause, capture the deadlock graph and analyze which statements and lock types are involved. Common fixes include reordering operations so competing transactions acquire locks in the same sequence, reducing transaction scope, and adding appropriate indexes to reduce lock duration.
For a full walkthrough of deadlock analysis, see Deadlocks guide. If you're using Azure SQL Database, see Analyze and prevent deadlocks.
Bulk load issues
Constraint violations during bulkcopy
Symptoms:
RuntimeError: CHECK constraint ... Conflict occurred in database ...
RuntimeError: Cannot insert duplicate key ... violation of PRIMARY KEY constraint
Cause:
Data in your batch violates table constraints (primary key, unique, CHECK, or foreign key).
Fix:
Validate data before loading. For large datasets, load into a staging table first, then merge into the 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()
For upsert patterns with staging tables, see Data loading and movement patterns.
Column mapping errors
Symptoms:
RuntimeError: Bulk copy failure - column count mismatch
Cause:
The number of columns in your data doesn't match the target table's column count, or columns are in the wrong order.
Fix:
Ensure your data matches the table schema exactly in order and count:
# 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)
Type mismatches during bulkcopy
Symptoms:
Data loads but values are truncated, rounded, or incorrect.
Cause:
Python values don't map cleanly to the target column types. Common cases: float values loaded into decimal columns (precision loss), or oversized strings loaded into fixed-length columns.
Fix:
Use the correct Python types that match your 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)
Numpy type binding failures
Symptoms:
Parameters silently fail or raise data type errors when using numpy integer or float types.
Cause:
Numpy types like numpy.int64 and numpy.int32 don't pass isinstance(x, int) in NumPy 2.x. The driver's type inference doesn't recognize them, which causes unexpected behavior.
Fix:
Convert numpy values to native Python types before 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"])}
)
For larger datasets, use the Arrow or pandas integration paths instead, which handle type conversion internally.
Bulkcopy with temp tables
Symptoms:
cursor.bulkcopy("#TempTable", data) raises RuntimeError: Invalid object name '#TempTable'.
Cause:
bulkcopy() can't resolve session temp tables (#tablename) due to metadata lookup limitations. Global temp tables (##tablename) and permanent tables work.
Fix:
Use a global temp table or a regular staging table:
# 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)
For small datasets where a session temp table is preferred, use executemany() instead:
cursor.execute("CREATE TABLE #Staging (ID INT, Name NVARCHAR(50))")
cursor.executemany("INSERT INTO #Staging (ID, Name) VALUES (?, ?)", rows)
Container and CI issues
Missing system libraries on Linux
Symptoms:
ImportError: libltdl.so.7: cannot open shared object file: No such file or directory
ImportError: libkrb5.so.3: cannot open shared object file
Fix:
Install the required system packages. The packages differ by distribution:
| Distribution | Install command |
|---|---|
| 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 |
For Dockerfile examples, see Container and local development.
macOS SSL errors after install
Symptoms:
SSL-related errors when connecting from macOS, especially on Apple Silicon.
Fix:
Install OpenSSL via Homebrew and set the linker flags:
brew install openssl
export LDFLAGS="-L/opt/homebrew/opt/openssl/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl/include"
Diagnostic tools
Enable driver logging
Use mssql_python.setup_logging() to enable comprehensive DEBUG logging for troubleshooting. All driver operations are logged, including SQL statements, parameters, internal ODBC operations, and connection state changes.
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")
Log files are written in CSV format and automatically rotate at 512 MB with five backups. Sensitive data like passwords and access tokens are automatically sanitized in log output.
To add your own log entries alongside driver logs, use 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
Logging has performance overhead. Enable it only when troubleshooting, not in production by default.
Get driver information
Retrieve the driver version and server details from an active connection:
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)}")
Check connection state
Test whether a connection is still open before attempting operations:
try:
cursor = conn.cursor()
cursor.execute("SELECT 1")
print("Connection is open")
except mssql_python.Error:
print("Connection is closed or broken")
Quick reference: Common errors
| Error | SQLSTATE | Common cause | Quick fix |
|---|---|---|---|
| Client unable to establish connection | 08001 | Server unreachable | Check server name/port |
| Login failed | 28000 | Wrong credentials | Verify username/password |
| Timeout expired | HYT00/HYT01 | Slow network | Increase timeout |
| Invalid object name | 42S02 | Wrong table/schema | Use fully qualified names |
| Syntax error | 42000 | SQL error | Use parameterized queries |
| Constraint violation | 23000 | FK/PK violation | Check data integrity |
| Deadlock | 40001 | Lock contention | Retry, then analyze the deadlock graph |