Skip to content

Commit 4a4c0b1

Browse files
feat: Implement MSSQL engine import validator for driver configuration and add corresponding tests
1 parent 9fffd1e commit 4a4c0b1

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

sqlmesh/core/config/connection.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1438,7 +1438,46 @@ class MSSQLConnectionConfig(ConnectionConfig):
14381438

14391439
type_: t.Literal["mssql"] = Field(alias="type", default="mssql")
14401440

1441-
_engine_import_validator = _get_engine_import_validator("pymssql", "mssql")
1441+
@model_validator(mode="before")
1442+
@classmethod
1443+
def _mssql_engine_import_validator(cls, data: t.Any) -> t.Any:
1444+
if not isinstance(data, dict):
1445+
return data
1446+
1447+
check_import = str_to_bool(str(data.pop("check_import", True)))
1448+
if not check_import:
1449+
return data
1450+
1451+
driver = data.get("driver", "pymssql")
1452+
1453+
try:
1454+
if driver == "pymssql":
1455+
importlib.import_module("pymssql")
1456+
elif driver == "pyodbc":
1457+
importlib.import_module("pyodbc")
1458+
else:
1459+
raise ValueError(f"Unsupported driver: {driver}")
1460+
except ImportError:
1461+
if debug_mode_enabled():
1462+
raise
1463+
1464+
logger.exception("Failed to import the MSSQL engine library")
1465+
1466+
if driver == "pymssql":
1467+
extra_name = "mssql"
1468+
elif driver == "pyodbc":
1469+
extra_name = "mssql-odbc"
1470+
else:
1471+
extra_name = "mssql"
1472+
1473+
raise ConfigError(
1474+
f"Failed to import the '{driver}' library for MSSQL connections. This may be due to a missing "
1475+
"or incompatible installation. Please ensure the required dependency is installed by "
1476+
f'running: `pip install "sqlmesh[{extra_name}]"`. For more details, check the logs '
1477+
"in the 'logs/' folder, or rerun the command with the '--debug' flag."
1478+
)
1479+
1480+
return data
14421481

14431482
@property
14441483
def _connection_kwargs_keys(self) -> t.Set[str]:

tests/core/test_connection_config.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import pytest
66
from _pytest.fixtures import FixtureRequest
7+
from unittest.mock import patch
78

89
from sqlmesh.core.config.connection import (
910
BigQueryConnectionConfig,
@@ -19,6 +20,7 @@
1920
SnowflakeConnectionConfig,
2021
TrinoAuthenticationMethod,
2122
AthenaConnectionConfig,
23+
MSSQLConnectionConfig,
2224
_connection_config_validator,
2325
_get_engine_import_validator,
2426
)
@@ -1127,3 +1129,54 @@ class TestConfigC(PydanticModel):
11271129
_engine_import_validator = _get_engine_import_validator("sqlmesh", "bigquery")
11281130

11291131
TestConfigC()
1132+
1133+
1134+
def test_mssql_engine_import_validator():
1135+
"""Test that MSSQL import validator respects driver configuration."""
1136+
with pytest.raises(
1137+
ConfigError,
1138+
match=re.escape(
1139+
"Failed to import the 'pyodbc' library for MSSQL connections. This may be due to a missing "
1140+
"or incompatible installation. Please ensure the required dependency is installed by "
1141+
'running: `pip install "sqlmesh[mssql-odbc]"`. For more details, check the logs '
1142+
"in the 'logs/' folder, or rerun the command with the '--debug' flag."
1143+
),
1144+
):
1145+
# Test PyODBC driver suggests mssql-odbc extra
1146+
with patch("importlib.import_module") as mock_import:
1147+
mock_import.side_effect = ImportError("No module named 'pyodbc'")
1148+
MSSQLConnectionConfig(host="localhost", driver="pyodbc")
1149+
1150+
with pytest.raises(
1151+
ConfigError,
1152+
match=re.escape(
1153+
"Failed to import the 'pymssql' library for MSSQL connections. This may be due to a missing "
1154+
"or incompatible installation. Please ensure the required dependency is installed by "
1155+
'running: `pip install "sqlmesh[mssql]"`. For more details, check the logs '
1156+
"in the 'logs/' folder, or rerun the command with the '--debug' flag."
1157+
),
1158+
):
1159+
# Test PyMSSQL driver suggests mssql extra
1160+
with patch("importlib.import_module") as mock_import:
1161+
mock_import.side_effect = ImportError("No module named 'pymssql'")
1162+
MSSQLConnectionConfig(host="localhost", driver="pymssql")
1163+
1164+
with pytest.raises(
1165+
ConfigError,
1166+
match=re.escape(
1167+
"Failed to import the 'pymssql' library for MSSQL connections. This may be due to a missing "
1168+
"or incompatible installation. Please ensure the required dependency is installed by "
1169+
'running: `pip install "sqlmesh[mssql]"`. For more details, check the logs '
1170+
"in the 'logs/' folder, or rerun the command with the '--debug' flag."
1171+
),
1172+
):
1173+
# Test default driver (pymssql) suggests mssql extra
1174+
with patch("importlib.import_module") as mock_import:
1175+
mock_import.side_effect = ImportError("No module named 'pymssql'")
1176+
MSSQLConnectionConfig(host="localhost") # No driver specified
1177+
1178+
# Test successful import doesn't raise exception
1179+
with patch("importlib.import_module") as mock_import:
1180+
mock_import.return_value = None
1181+
config = MSSQLConnectionConfig(host="localhost", driver="pyodbc")
1182+
assert config.driver == "pyodbc"

0 commit comments

Comments
 (0)