El controlador mssql-python define una jerarquía estándar de excepciones, patrones comunes de gestión de errores y mapeos de código SQLSTATE para SQL Server y Azure SQL.
Jerarquía de excepciones
El controlador mssql-python sigue la jerarquía de excepciones DB-API 2.0 (PEP 249):
Exception (builtins)
├── Warning
└── Error
├── InterfaceError
└── DatabaseError
├── DataError
├── OperationalError
├── IntegrityError
├── InternalError
├── ProgrammingError
└── NotSupportedError
ConnectionStringParseError (standalone, not part of hierarchy)
Descripciones de excepciones
Detecta la excepción más específica que se adapte a tu situación. Por ejemplo, detectar IntegrityError violaciones de restricciones en INSERT/UPDATE operaciones y ProgrammingError problemas de sintaxis SQL durante el desarrollo. Captura la clase base Error solo como plan B.
| Exception |
Cuando se levanta |
Warning |
Advertencias no fatales de la base de datos. |
Error |
Clase base para todos los errores de la base de datos. |
InterfaceError |
Errores relacionados con la interfaz de la base de datos (controlador), no con la base de datos en sí. |
DatabaseError |
Errores relacionados con la base de datos. |
DataError |
Errores debidos a problemas con los datos procesados (división por cero, valor fuera de rango). |
OperationalError |
Errores relacionados con la operación de la base de datos (pérdida de conexión, asignación de memoria, errores de transacción). |
IntegrityError |
Errores cuando se ve afectada la integridad de la base de datos (violación de clave extranjera, restricción única). |
InternalError |
Errores internos de la base de datos (cursor no válido, transacción desincronizada). |
ProgrammingError |
Errores de programación (errores de sintaxis, tabla no encontrada, número incorrecto de parámetros). |
NotSupportedError |
Función no soportada por la base de datos ni por el controlador. |
ConnectionStringParseError |
Sintaxis de cadena de conexión inválida o palabras clave desconocidas. |
Gestión básica de errores
Utiliza bloques try-except para gestionar errores de base de datos:
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()
Excepciones de acceso a través de la conexión
Puedes detectar excepciones a través de la instancia de conexión:
try:
cursor.execute("INVALID SQL")
except conn.ProgrammingError as e:
print(f"Caught via connection: {e}")
Estructura de mensajes de error
Los objetos de excepción mssql-python exponen tres atributos que provienen de la clase base delException controlador:
| Attribute |
Source |
Descripción |
driver_error |
Controlador de Python |
El texto estandarizado en inglés elegido por el estado SQLS devolvía de ODBC (por ejemplo, "Communication link failure", "Invalid authorization specification", "Syntax error or access violation"). Estable entre lanzamientos; Seguro para hacer substring match. |
ddbc_error |
Conectividad Directa con la Base de Datos (DDBC) |
El mensaje del lado del servidor, típicamente precedido por [Microsoft][SQL Server]. El formato no es un contrato estable. |
message |
Compuesto |
f"Driver Error: {driver_error}; DDBC Error: {ddbc_error}". Esto es lo que str(exc) devuelve. |
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: ...
El número de error del motor de SQL Server (como 208 o 40501) no está expuesto como atributo y no está incrustado de forma fiable en ninguna de las cadenas. Clasificar errores por subclase de excepción más driver_error texto. Para la limitación de Azure SQL, véase lógica de intento.
Clasificación SQLSTATE
mssql-python utiliza el estado SQLSTATE devuelto por ODBC para elegir tanto la subclase de excepción de Python como el driver_error texto. El mapeo completo de SQLSTATE → excepciones está en exceptions.py el código fuente del driver. La siguiente sección enumera los SQLSTATEs que aparecen con mayor frecuencia con SQL Server y Azure SQL.
Errores de conexión
Fallos de conexión por mssql_python.connect() elevación mssql_python.OperationalError, igual que otros fallos de conectividad:
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"
Errores de cadena de conexión
Los errores de análisis de cadenas de conexión aumentan 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'
Referencia del código SQLSTATE
Los códigos SQLSTATE son códigos de cinco caracteres que identifican condiciones de error. Los dos primeros caracteres indican la clase, y los tres últimos indican la subclase. Rara vez necesitas inspeccionar estos códigos directamente. En su lugar, selecciona el tipo de excepción de Python apropiado (listado en la columna "Excepción"). Utiliza códigos SQLSTATE cuando necesites distinguir entre condiciones de error específicas dentro del mismo tipo de excepción, por ejemplo para diferenciar un bloqueo (40001) de un fallo general de conexión (08S01).
Clase 00 - Finalización exitosa
| SQLSTATE |
Exception |
Descripción |
| 00000 |
None |
Success |
Clase 01 - Advertencia
| SQLSTATE |
Exception |
Descripción |
| 01000 |
Advertencia |
Advertencia general |
| 01001 |
Advertencia |
Conflicto de la operación del cursor |
| 01002 |
Advertencia |
Error de desconexión |
| 01003 |
DataError |
Valor NULL eliminado en la función set |
| 01004 |
DataError |
Datos de cadena, truncamiento derecho |
| 01006 |
Advertencia |
Privilegio no revocado |
| 01007 |
Advertencia |
Privilegio no concedido |
| 01S00 |
Advertencia |
Atributo cadena de conexión no válido |
| 01S01 |
Advertencia |
Error en la fila |
| 01S02 |
Advertencia |
Valor de opción cambiado |
Clase 07 - Error SQL dinámico
| SQLSTATE |
Exception |
Descripción |
| 07001 |
ErrorProgramación |
Número incorrecto de parámetros |
| 07002 |
ErrorProgramación |
Campo COUNT incorrecto |
| 07005 |
ErrorProgramación |
Instrucción preparada, no una especificación de cursor |
| 07006 |
ErrorProgramación |
Infracción de atributo de tipo de datos restringido |
| 07009 |
ErrorProgramación |
Índice de descriptores inválidos |
| 07S01 |
ErrorProgramación |
Uso no válido del parámetro predeterminado |
Clase 08 - Excepción de conexión
| SQLSTATE |
Exception |
Descripción |
| 08001 |
ErrorOperacional |
El cliente no puede establecer la conexión |
| 08002 |
ErrorOperacional |
Nombre de conexión en uso |
| 08003 |
ErrorOperacional |
La conexión no existe |
| 08004 |
ErrorOperacional |
El servidor rechazó la conexión |
| 08007 |
ErrorOperacional |
Fallo de conexión durante la transacción |
| 08S01 |
ErrorOperacional |
Error de vínculo de comunicación |
Clase 21 - Violación de cardinalidad
| SQLSTATE |
Exception |
Descripción |
| 21S01 |
ErrorProgramación |
La lista de valores de inserción no coincide con la lista de columnas |
| 21S02 |
ErrorProgramación |
El grado de la tabla derivada no coincide con la lista de columnas |
Clase 22 - Excepción de datos
| SQLSTATE |
Exception |
Descripción |
| 22001 |
DataError |
Datos de cadena, truncamiento derecho |
| 22002 |
DataError |
Variable de indicador necesaria pero no proporcionada |
| 22003 |
DataError |
Valor numérico fuera del intervalo |
| 22007 |
DataError |
Formato datetime no válido |
| 22008 |
DataError |
Desbordamiento de campo datetime |
| 22012 |
DataError |
División por cero |
| 22015 |
DataError |
Desbordamiento de campo de intervalo |
| 22018 |
DataError |
Valor de carácter no válido para la especificación de conversión |
| 22019 |
DataError |
Carácter de escape no válido |
| 22025 |
DataError |
Secuencia de escape no válida |
| 22026 |
DataError |
Datos de cadena, desigualdad de longitud |
Clase 23 - Violación de restricciones de integridad
| SQLSTATE |
Exception |
Descripción |
| 23000 |
IntegrityError |
Violación de restricciones de integridad (general) |
Clase 24 - Estado del cursor inválido
| SQLSTATE |
Exception |
Descripción |
| 24000 |
Error interno |
Estado de cursor no válido |
Clase 25 - Estado de transacción inválido
| SQLSTATE |
Exception |
Descripción |
| 25000 |
ErrorOperacional |
Estado de la transacción inválido |
| 25S01 |
ErrorOperacional |
Estado de la transacción desconocido |
| 25S02 |
ErrorOperacional |
La transacción sigue activa |
| 25S03 |
ErrorOperacional |
La transacción se revierte |
Clase 28 - Especificación de autorización inválida
| SQLSTATE |
Exception |
Descripción |
| 28000 |
ErrorOperacional |
Especificación de autorización inválida (inicio de sesión fallido) |
Clase 34 - Nombre de cursor inválido
| SQLSTATE |
Exception |
Descripción |
| 34000 |
ErrorProgramación |
Nombre de cursor no válido |
Clase 3C - Nombre duplicado del cursor
| SQLSTATE |
Exception |
Descripción |
| 3C000 |
ErrorProgramación |
Nombre de cursor duplicado |
Clase 3D - Nombre de catálogo inválido
| SQLSTATE |
Exception |
Descripción |
| 3D000 |
ErrorProgramación |
Nombre de catálogo no válido |
Clase 3F - Nombre de esquema inválido
| SQLSTATE |
Exception |
Descripción |
| 3F000 |
ErrorProgramación |
Nombre de esquema no válido |
Clase 40 - Revertir transacciones
| SQLSTATE |
Exception |
Descripción |
| 40001 |
ErrorOperacional |
Fallo de serialización (bloqueo) |
| 40002 |
ErrorOperacional |
La violación de restricciones de integridad provocó retroceso |
| 40003 |
ErrorOperacional |
Finalización de instrucciones desconocida |
Clase 42 - Error de sintaxis o violación de la regla de acceso
| SQLSTATE |
Exception |
Descripción |
| 42000 |
ErrorProgramación |
Error de sintaxis o infracción de acceso |
| 42S01 |
ErrorProgramación |
Ya existe una tabla base o vista |
| 42S02 |
ErrorProgramación |
Tabla base o vista no encontrada |
| 42S11 |
ErrorProgramación |
El índice ya existe |
| 42S12 |
ErrorProgramación |
No se encontró el índice |
| 42S21 |
ErrorProgramación |
La columna ya existe |
| 42S22 |
ErrorProgramación |
No se encontró la columna. |
Clase 44 - VIOLACIÓN DE LA OPCIÓN DE VERIFICACIÓN
| SQLSTATE |
Exception |
Descripción |
| 44 000 |
IntegrityError |
Infracción de WITH CHECK OPTION |
Clase HY - Condición específica de CLI
| SQLSTATE |
Exception |
Descripción |
| HY000 |
DatabaseError |
Error genérico |
| HY001 |
ErrorOperacional |
Error de asignación de memoria |
| HY003 |
ErrorProgramación |
Tipo de búfer de aplicación no válido |
| HY004 |
ErrorProgramación |
Tipo de datos SQL no válido |
| HY007 |
ErrorProgramación |
La instrucción asociada no está preparada |
| HY008 |
ErrorOperacional |
Operación cancelada |
| HY009 |
ErrorProgramación |
Uso no válido del puntero nulo |
| HY010 |
ErrorProgramación |
Error de secuencia de funciones |
| HY011 |
ErrorProgramación |
El atributo no se puede establecer ahora |
| HY012 |
ErrorProgramación |
Código de operación de transacción inválido |
| HY013 |
ErrorOperacional |
Error de administración de memoria |
| HY014 |
ErrorOperacional |
Límite de número de asas superadas |
| HY015 |
ErrorProgramación |
No hay ningún nombre de cursor disponible |
| HY016 |
ErrorProgramación |
No se puede modificar un descriptor de fila de implementación |
| HY017 |
ErrorProgramación |
Uso inválido del handle descriptor asignado automáticamente |
| HY018 |
ErrorOperacional |
Servidor rechazó la solicitud de cancelación |
| HY019 |
ErrorProgramación |
Datos no caracteres y no binarios enviados en fragmentos |
| HY020 |
DataError |
Intento de concatenar un valor nulo |
| HY021 |
ErrorProgramación |
Información de descriptores inconsistente |
| HY024 |
ErrorProgramación |
Valor de atributo no válido |
| HY090 |
ErrorProgramación |
Longitud de búfer o cadena no válida |
| HY091 |
ErrorProgramación |
Identificador de campo descriptor inválido |
| HY092 |
ErrorProgramación |
Identificador de atributo/opción inválido |
| HY095 |
ErrorProgramación |
Tipo de función fuera de rango |
| HY096 |
ErrorProgramación |
Tipo de información inválido |
| HY097 |
ErrorProgramación |
Tipo de columna fuera de rango |
| HY098 |
ErrorProgramación |
Tipo de mira fuera de alcance |
| HY099 |
ErrorProgramación |
Tipo nulo fuera de rango |
| HY100 |
ErrorProgramación |
Tipo de opción de unicidad fuera del intervalo |
| HY101 |
ErrorProgramación |
Tipo de opción de precisión fuera del intervalo |
| HY103 |
ErrorProgramación |
Código de recuperación inválido |
| HY104 |
ErrorProgramación |
Precisión o valor de escala no válidos |
| HY105 |
ErrorProgramación |
Tipo de parámetro no válido |
| HY106 |
ErrorProgramación |
Tipo de recolección fuera de alcance |
| HY107 |
ErrorProgramación |
Valor de la fila fuera de rango |
| HY109 |
ErrorProgramación |
Posición del cursor no válida |
| HY110 |
ErrorProgramación |
Completación del controlador inválido |
| HY111 |
ErrorProgramación |
Valor de marcador inválido |
| HYC00 |
NotSupportedError |
Característica opcional no implementada |
| HYT00 |
ErrorOperacional |
Se ha agotado el tiempo de espera |
| HYT01 |
ErrorOperacional |
Se ha agotado el tiempo de espera de la conexión. |
Clase IM - Error del entrenador del piloto
| SQLSTATE |
Exception |
Descripción |
| IM001 |
InterfaceError |
El controlador no admite esta función |
| IM002 |
InterfaceError |
Nombre de la fuente de datos no encontrado |
| IM003 |
InterfaceError |
No se pudo cargar el controlador especificado |
| IM004 |
InterfaceError |
El SQLAllocHandle del controlador en SQL_HANDLE_ENV falló |
| IM005 |
InterfaceError |
El SQLAllocHandle del controlador en SQL_HANDLE_DBC falló |
| IM006 |
InterfaceError |
El SQLSetConnectAttr del controlador falló |
| IM007 |
InterfaceError |
No se especifica ninguna fuente de datos ni controlador |
| IM008 |
InterfaceError |
Diálogo fallido |
| IM009 |
InterfaceError |
No se puede cargar el archivo DLL de traducción |
| IM010 |
InterfaceError |
Nombre del origen de datos demasiado largo |
| IM011 |
InterfaceError |
Nombre del controlador demasiado largo |
| IM012 |
InterfaceError |
Error de sintaxis de palabra clave DRIVER |
| IM014 |
InterfaceError |
DSN inválido |
| IM015 |
InterfaceError |
Fuente de datos de archivo corrupta |
Números de error comunes en SQL Server
Más allá de SQLSTATE, SQL Server proporciona números de error nativos entre paréntesis. Estos son los errores que es más probable que encuentres en el código de la aplicación. Construye la lógica de reintento alrededor del error 1205 (bloqueo) y errores de conexión transitoria (véase lógica de reintento).
| Error |
Patrón de mensaje |
Resolución |
| 208 |
Nombre de objeto no válido. |
Verifica que la tabla o vista exista y comprueba la calificación del esquema. |
| 547 |
Infracción de restricción |
Falló una restricción de clave extranjera o comprobación. |
| 2627 |
Violación única de restricciones |
Se insertó un valor clave duplicado. |
| 2601 |
Violación única del índice |
Existe una clave duplicada en el índice. |
| 4060 |
No se puede abrir la base de datos |
La base de datos no existe o se niega el acceso. |
| 18456 |
Error de inicio de sesión |
Fallo de autenticación. Consulta las credenciales. |
| 1205 |
Víctima de interbloqueo |
La transacción se revirtió. Vuelva a intentar la operación. |
Referencia rápida de síntoma a excepción
Utiliza esta tabla para mapear los síntomas comunes al tipo de excepción que deberías detectar:
| Síntoma |
Exception |
Causa probable |
| "Inicio de sesión fallido para el usuario" |
OperationalError |
Credenciales incorrectas o usuario no asignado a la base de datos. |
| "Cliente incapaz de establecer conexión" |
OperationalError |
Servidor inalcanzable, problema con firewall o DNS. |
| "Tiempo muerto expirado" |
OperationalError |
Tiempo de espera de consulta o conexión. Aumenta el tiempo de espera o optimiza la consulta. |
| "Nombre de objeto inválido" |
ProgrammingError |
No existe la tabla ni el esquema no está especificado. |
| "Sintaxis incorrecta" |
ProgrammingError |
Error de sintaxis SQL. Consulta de prueba en SSMS. |
| "Número incorrecto de parámetros" |
ProgrammingError |
El recuento de parámetros no coincide con los marcadores de posición. |
| "Violación de la CLAVE PRIMARIA" |
IntegrityError |
Duplicar la llave. Úsalo MERGE o comprueba antes de insertarlo. |
| "Violación de CLAVE EXTRANJERA" |
IntegrityError |
La fila referenciada no existe. Inserta primero a los padres. |
| "La transacción quedó bloqueada" |
OperationalError (error 1205) |
Contención de bloqueo. Implemente la lógica de reintento. |
| "Los datos de cadena o binarios se truncarían" |
DataError |
El valor supera la longitud de la columna. Revisa los datos o aumenta el tamaño de la columna. |
| "Conversión fallida" |
DataError |
Error de coincidencia de tipos. Usa el tipo correcto de Python para la columna. |
| "Palabra clave desconocida" |
ConnectionStringParseError |
Error tipográfico en la palabra clave de cadena de conexión. |
| "callproc no es compatible" |
NotSupportedError |
Utilice cursor.execute("EXECUTE ...") en su lugar. |
procedimientos recomendados
-
Detecta excepciones específicas antes que genéricas. Ordena de más específico (
IntegrityError) a menos específico (Error).
-
Siempre maneja IntegrityError para las operaciones de modificación de datos. Se esperan violaciones de restricciones en el funcionamiento normal (por ejemplo, un usuario que intenta crear un nombre de usuario duplicado).
-
Registra el contexto completo del error para la resolución de problemas. La excepción expone
driver_error (texto estable derivado de SQLSTATE) y ddbc_error (mensaje del lado del servidor). Registrar ambos; clasificar en driver_error.
-
Implementa lógica de reintento para errores transitorios (fallos de conexión, bloqueos). Consulta lógica de reintento.
-
Utiliza rollback() en los gestores de excepciones para limpiar transacciones fallidas. Sin una reversión explícita, la conexión permanece en estado de transacción fallida.
Contenido relacionado