Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Diagnostica y resuelve problemas comunes al usar el controlador mssql-python para conectarte a SQL Server, Azure SQL Database, Azure SQL Managed Instance y base de datos SQL en Microsoft Fabric.
Problemas de instalación
Fallos de instalación de PIP o compilación desde el código fuente
Síntomas:
error: Microsoft Visual C++ 14.0 or greater is required
ERROR: Failed building wheel for mssql-python
Posibles causas y soluciones:
No hay volante preensamblado para tu plataforma
- Comprueba que tienes una versión de Python compatible (versiones 3.10 y posteriores) y una plataforma. Consulta el ciclo de vida del soporte para la matriz de compatibilidad. Actualiza pip antes de instalar con
pip install --upgrade pip. Para entornos de equipo reproducibles, utiliza el flujo de trabajo fijado en Repeatable deployments o los patrones de contenedores de Container and local development para reducir la desviación en las máquinas locales.
- Comprueba que tienes una versión de Python compatible (versiones 3.10 y posteriores) y una plataforma. Consulta el ciclo de vida del soporte para la matriz de compatibilidad. Actualiza pip antes de instalar con
Entorno virtual no activado
- Activa primero tu entorno virtual. Instalar Python en el sistema puede causar errores de permisos o conflictos.
python -m venv .venv .venv\Scripts\activate pip install mssql-python
-
Bibliotecas del sistema Linux que faltan
- El controlador requiere un pequeño conjunto de librerías de sistema en Linux. Consulta Dependencias específicas de plataforma para los paquetes a instalar.
Instalaciones de controladores en conflicto
Síntomas:
Errores de importación o comportamientos inesperados tras instalarlos mssql-python junto pyodbc en el mismo entorno.
Corrección:
mssql-python y pyodbc pueden coexistir. Si ves conflictos, crea un entorno virtual limpio:
python -m venv .venv --clear
.venv\Scripts\activate
pip install mssql-python
Problemas de conexión
No se puede conectar al servidor
Síntomas:
OperationalError: [08001] (0) Client unable to establish connection
Posibles causas y soluciones:
Servidor no accesible
- Verifica que el nombre del servidor y el puerto sean correctos.
- Comprobar conectividad de red:
ping servernameotelnet servername 1433. - Asegúrate de que el cortafuegos permita conexiones salientes en el puerto 1433.
SQL Server no está en ejecución
- Verifica que el servicio de SQL Server está activado.
- Para instancias nombradas, verifica que el servicio SQL Server Browser esté en funcionamiento.
Reglas de firewall Azure SQL
- Añade la IP de tu cliente a las reglas del firewall Azure SQL en el portal de Azure.
- Para Azure SQL Managed Instance, asegúrate de conectarte desde una red permitida.
# 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}")
Error de inicio de sesión
Síntomas:
OperationalError: [28000] (18456) Login failed for user 'username'.
Posibles causas y soluciones:
Incompatibilidad en el modo de autenticación
- Para Azure SQL Database, Azure SQL Managed Instance y SQL Database en Fabric, se prefiere un modo de autenticación de Microsoft Entra como
Authentication=ActiveDirectoryDefault. - Si usas autenticación SQL intencionadamente, verifica que el servidor lo permita y que usas el formato de inicio de sesión correcto para ese endpoint.
- Para Azure SQL Database, Azure SQL Managed Instance y SQL Database en Fabric, se prefiere un modo de autenticación de Microsoft Entra como
Credenciales de autenticación SQL incorrectas
- Verifica el nombre de usuario y la contraseña.
- Para Azure SQL, incluye el nombre de usuario completo:
username@servername.
El usuario no existe en la base de datos
- Verifica que el usuario tenga acceso a la base de datos especificada.
- Comprueba si el inicio de sesión está asignado a un usuario de la base de datos.
Autenticación no configurada
- Utiliza la autenticación de Microsoft Entra (recomendada):
Authentication=ActiveDirectoryDefault. - Si estás solucionando problemas en un SQL Server local que debería aceptar autenticación SQL, verifica que SQL Server use autenticación en modo mixto.
- Utiliza la autenticación de Microsoft Entra (recomendada):
Tiempo de espera de conexión
Síntomas:
OperationalError: [HYT00] (0) Timeout expired
OperationalError: [HYT01] (0) Connection timeout expired
Posibles causas y soluciones:
El servidor tarda en responder
- Aumenta el tiempo de espera de conexión:
conn = mssql_python.connect(connection_string, timeout=60)Latencia de red
- Comprueba la ruta de red hacia el servidor.
- Considera usar una ruta de red o VPN más corta.
Servidor bajo alta carga
- Prueba a conectarte en horas valle.
- Contacta con el administrador de tu base de datos.
Errores de certificado SSL
Síntomas:
OperationalError: [08001] SSL Provider: The certificate chain was issued by an authority that is not trusted
Soluciones:
Primero, prefiera un certificado de confianza o los patrones de desarrollo local en Contenedor y desarrollo local. Úsalo TrustServerCertificate=yes solo para desarrollo local contra un servidor que controlas.
Para desarrollo y pruebas con un certificado autofirmado:
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 es un recurso de respaldo solo local. No lo lleves a devcontainers compartidos, pipelines de CI o despliegues en producción. Para una orientación más general, véase Cifrado y certificados.
Para la producción, asegúrese de que se instalen los certificados adecuados y se utilicen:
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"HostnameInCertificate=<server>.domain.com;"
)
Problemas de ejecución de consultas
Tabla u objeto no encontrado
Síntomas:
ProgrammingError: [42S02] (208) Invalid object name 'TableName'.
Posibles causas y soluciones:
Contexto incorrecto de la base de datos
# Ensure you're connected to the correct database cursor.execute("SELECT DB_NAME()") print(cursor.fetchone()[0])Esquema no especificado
# Use fully qualified name cursor.execute("SELECT * FROM dbo.TableName")La tabla no existe
# Check if table exists cursor.execute(""" SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TableName' """)
Error de sintaxis
Síntomas:
ProgrammingError: [42000] (102) Incorrect syntax near '...'.
Soluciones:
Prueba primero SQL en SSMS para verificar la sintaxis
Comprueba el escape de cadenas - usa consultas parametrizadas:
# 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})
Errores de parámetros
Síntomas:
ProgrammingError: [07001] Wrong number of parameters
Soluciones:
Cuenta los marcadores de posición y los parámetros - deben coincidir
Elige el estilo de parámetro adecuado:
# 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())
Problemas con el tipo de datos
Errores de conversión de fecha y hora
Síntomas:
DataError: [22007] Invalid datetime format
Soluciones:
Usa objetos de fecha-hora en Python en lugar de cadenas:
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())
Problemas de precisión decimal
Síntomas:
Los números aparecen truncados o redondeados incorrectamente.
Soluciones:
Uso decimal.Decimal para valores numéricos precisos:
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")}
)
Problemas de codificación Unicode
Síntomas:
Los caracteres especiales aparecen distorsionados o causan errores.
Soluciones:
Utiliza columnas NVARCHAR para los datos Unicode en tu base de datos
Pasa cadenas directamente : el controlador se encarga de la codificación:
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())
Problemas de rendimiento
Ejecución lenta de consultas
Posibles causas y soluciones:
Índices faltantes: Revisa el plan de ejecución de consultas en SSMS.
Conjuntos de resultados grandes: Usar
fetchmany()en lugar defetchall():cursor.arraysize = 1000 while True: rows = cursor.fetchmany() if not rows: break process_rows(rows)Agrupación de conexiones desactivada: Habilitar agrupación:
import mssql_python mssql_python.pooling(max_size=20, idle_timeout=300)
Problemas de memoria con resultados grandes
Síntomas:
El proceso de Python se queda sin memoria.
Soluciones:
Resultados del flujo en lugar de cargarlo todo en memoria:
cursor.execute("SELECT * FROM LargeTable") for row in cursor: # Iterates one row at a time process_row(row)Utiliza la paginación en el servidor:
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
Problemas de transacciones
Alcance de tablas temporales con autocommit
Las tablas temporales (#tablename) creadas dentro de una transacción desaparecen cuando la transacción se revierte. Esta es una fuente común de confusión cuando el autocommit está apagado (el valor por defecto):
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")
Solución: Confirma la transacción inmediatamente después de crear una tabla temporal, o usa el modo de confirmación automática:
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()
Las sentencias DDL que requieren modo de compromiso automático, como CREATE DATABASE, fallan dentro de una transacción abierta. Establece el autocommit antes de ejecutarlos:
conn.autocommit = True
cursor.execute("CREATE DATABASE TestDB")
conn.autocommit = False
Transacción no comprometida
Síntomas:
Los cambios en los datos no persisten después de cerrar la conexión.
Solution:
Con autocommit=False (por defecto), debes llamar a 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!
O usar modo de compromiso automático:
conn = mssql_python.connect(connection_string, autocommit=True)
Errores de interbloqueo
Síntomas:
OperationalError: [40001] (1205) Transaction ... was deadlocked on lock resources with another process
Solution:
La lógica de reintentos (véase lógica de reintentos) gestiona el fallo inmediato, pero los bloqueos recurrentes indican un problema de diseño. Para solucionar la causa raíz, captura el gráfico de bloqueo y analiza qué sentencias y tipos de bloqueo están implicados. Las soluciones comunes incluyen reordenar operaciones para que las transacciones competidoras adquieran bloqueos en la misma secuencia, reducir el alcance de la transacción y añadir índices apropiados para reducir la duración del bloqueo.
Para una guía completa del análisis de bloqueos, consulta la guía de bloqueos. Si usas Azure SQL Database, consulta Analizar y prevenir bloqueos.
Problemas de carga masiva
Infracciones de restricciones durante la copia masiva
Síntomas:
RuntimeError: CHECK constraint ... Conflict occurred in database ...
RuntimeError: Cannot insert duplicate key ... violation of PRIMARY KEY constraint
Causa:
Los datos de tu lote violan las restricciones de la tabla (clave primaria, única, CHECK o clave foránea).
Corrección:
Valida los datos antes de cargar. Para conjuntos de datos grandes, carga primero en una tabla intermedia y luego combina en la tabla de destino:
# 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()
Para patrones upsert con tablas de etapas, véase Patrones de carga y movimiento de datos.
Errores de mapeo de columnas
Síntomas:
RuntimeError: Bulk copy failure - column count mismatch
Causa:
El número de columnas en tus datos no coincide con el número de columnas de la tabla objetivo, o las columnas están en un orden incorrecto.
Corrección:
Asegúrate de que tus datos coincidan exactamente con el esquema de la tabla en orden y cantidad:
# 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)
Desajustes de tipo durante la copia masiva
Síntomas:
Los datos se cargan, pero los valores están truncados, redondeados o incorrectos.
Causa:
Los valores de Python no se corresponden claramente con los tipos de columna destino. Casos comunes: float valores cargados en decimal columnas (pérdida de precisión), o cadenas sobredimensionadas cargadas en columnas de longitud fija.
Corrección:
Utiliza los tipos de Python correctos que coincidan con tu esquema:
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)
Fallos de vinculación de tipos de NumPy
Síntomas:
Los parámetros fallan silenciosamente o generan errores de tipo de dato al usar números enteros o tipos float.
Causa:
Los tipos de NumPy como numpy.int64 y numpy.int32 no superan isinstance(x, int) en NumPy 2.x. La inferencia de tipo del conductor no los reconoce, lo que provoca un comportamiento inesperado.
Corrección:
Convierte los valores numpy a tipos nativos de Python antes de asignar:
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"])}
)
Para conjuntos de datos más grandes, utiliza en su lugar las vías de integración de Arrow o pandas, que gestionan internamente la conversión de tipos.
Bulkcopy con tablas temporales
Síntomas:
cursor.bulkcopy("#TempTable", data) genera RuntimeError: Invalid object name '#TempTable'.
Causa:
bulkcopy() No puedo resolver tablas temporales de sesión (#tablename) debido a limitaciones de búsqueda de metadatos. Las tablas temporales globales (##tablename) y las tablas permanentes funcionan.
Corrección:
Utiliza una tabla temporal global o una tabla de ensayo normal:
# 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)
Para conjuntos de datos pequeños donde se prefiere una tabla temporal de sesión, use executemany() en su lugar:
cursor.execute("CREATE TABLE #Staging (ID INT, Name NVARCHAR(50))")
cursor.executemany("INSERT INTO #Staging (ID, Name) VALUES (?, ?)", rows)
Problemas de contenedores y CI
Bibliotecas del sistema ausentes en Linux
Síntomas:
ImportError: libltdl.so.7: cannot open shared object file: No such file or directory
ImportError: libkrb5.so.3: cannot open shared object file
Corrección:
Instala los paquetes de sistema necesarios. Los paquetes difieren por distribución:
| Distribution | Comando Install |
|---|---|
| Ubuntu/Debian | sudo apt-get install libltdl7 libkrb5-3 libgssapi-krb5-2 |
| Red Hat / Fedora | sudo dnf install libtool-ltdl krb5-libs |
| Alpino | apk add libltdl krb5-libs |
Para ejemplos de Dockerfile, véase Contenedores y desarrollo local.
Errores SSL de macOS tras la instalación
Síntomas:
Errores relacionados con SSL al conectarse desde macOS, especialmente en Apple Silicon.
Corrección:
Instala OpenSSL a través de Homebrew y establece las banderas de enlace:
brew install openssl
export LDFLAGS="-L/opt/homebrew/opt/openssl/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl/include"
Herramientas de diagnóstico
Habilitar el registro del controlador
Úsalo mssql_python.setup_logging() para habilitar un registro DEBUG completo para la resolución de problemas. Todas las operaciones del controlador se registran, incluyendo sentencias SQL, parámetros, operaciones ODBC internas y cambios en el estado de la conexión.
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")
Los archivos de registro se escriben en formato CSV y rotan automáticamente a 512 MB con cinco copias de seguridad. Datos sensibles como contraseñas y tokens de acceso se desinfectan automáticamente en la salida del log.
Para añadir sus propias entradas de registro junto con los registros del controlador, 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
El registro supone una sobrecarga de rendimiento. Actívala solo cuando estés resolviendo problemas, no en producción por defecto.
Obtener información del conductor
Recupera la versión del controlador y los detalles del servidor de una conexión activa:
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)}")
Comprobación del estado de conexión
Prueba si una conexión sigue abierta antes de intentar operar:
try:
cursor = conn.cursor()
cursor.execute("SELECT 1")
print("Connection is open")
except mssql_python.Error:
print("Connection is closed or broken")
Referencia rápida: Errores comunes
| Error | SQLSTATE | Causa común | Corrección rápida |
|---|---|---|---|
| El cliente no puede establecer la conexión | 08001 | Servidor inaccesible | Comprobar nombre del servidor/puerto |
| Error de inicio de sesión | 28000 | Credenciales incorrectas | Verifica nombre de usuario/contraseña |
| Se ha agotado el tiempo de espera | HYT00/HYT01 | Red lenta | Aumentar tiempo de espera |
| Nombre de objeto no válido. | 42S02 | Tabla/esquema incorrecto | Utiliza nombres plenamente cualificados |
| Error de sintaxis | 42000 | Error de SQL | Uso de consultas con parámetros |
| Infracción de restricción | 23000 | Infracción FK/PK | Comprobar la integridad de los datos |
| Deadlock | 40001 | Contención de bloqueo | Vuelve a intentarlo y luego analiza el gráfico de bloqueo |