sqlmesh 0.191.1.dev1__py3-none-any.whl → 0.191.1.dev2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sqlmesh/_version.py +2 -2
- sqlmesh/core/config/connection.py +120 -7
- sqlmesh/core/engine_adapter/mssql.py +4 -0
- {sqlmesh-0.191.1.dev1.dist-info → sqlmesh-0.191.1.dev2.dist-info}/METADATA +5 -1
- {sqlmesh-0.191.1.dev1.dist-info → sqlmesh-0.191.1.dev2.dist-info}/RECORD +9 -9
- {sqlmesh-0.191.1.dev1.dist-info → sqlmesh-0.191.1.dev2.dist-info}/WHEEL +0 -0
- {sqlmesh-0.191.1.dev1.dist-info → sqlmesh-0.191.1.dev2.dist-info}/entry_points.txt +0 -0
- {sqlmesh-0.191.1.dev1.dist-info → sqlmesh-0.191.1.dev2.dist-info}/licenses/LICENSE +0 -0
- {sqlmesh-0.191.1.dev1.dist-info → sqlmesh-0.191.1.dev2.dist-info}/top_level.txt +0 -0
sqlmesh/_version.py
CHANGED
|
@@ -17,5 +17,5 @@ __version__: str
|
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
|
18
18
|
version_tuple: VERSION_TUPLE
|
|
19
19
|
|
|
20
|
-
__version__ = version = '0.191.1.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 191, 1, '
|
|
20
|
+
__version__ = version = '0.191.1.dev2'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 191, 1, 'dev2')
|
|
@@ -55,11 +55,10 @@ MOTHERDUCK_TOKEN_REGEX = re.compile(r"(\?|\&)(motherduck_token=)(\S*)")
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
def _get_engine_import_validator(
|
|
58
|
-
import_name: str, engine_type: str, extra_name: t.Optional[str] = None
|
|
58
|
+
import_name: str, engine_type: str, extra_name: t.Optional[str] = None, decorate: bool = True
|
|
59
59
|
) -> t.Callable:
|
|
60
60
|
extra_name = extra_name or engine_type
|
|
61
61
|
|
|
62
|
-
@model_validator(mode="before")
|
|
63
62
|
def validate(cls: t.Any, data: t.Any) -> t.Any:
|
|
64
63
|
check_import = (
|
|
65
64
|
str_to_bool(str(data.pop("check_import", True))) if isinstance(data, dict) else True
|
|
@@ -83,7 +82,7 @@ def _get_engine_import_validator(
|
|
|
83
82
|
|
|
84
83
|
return data
|
|
85
84
|
|
|
86
|
-
return validate
|
|
85
|
+
return model_validator(mode="before")(validate) if decorate else validate
|
|
87
86
|
|
|
88
87
|
|
|
89
88
|
class ConnectionConfig(abc.ABC, BaseConfig):
|
|
@@ -1422,17 +1421,50 @@ class MSSQLConnectionConfig(ConnectionConfig):
|
|
|
1422
1421
|
autocommit: t.Optional[bool] = False
|
|
1423
1422
|
tds_version: t.Optional[str] = None
|
|
1424
1423
|
|
|
1424
|
+
# Driver options
|
|
1425
|
+
driver: t.Literal["pymssql", "pyodbc"] = "pymssql"
|
|
1426
|
+
# PyODBC specific options
|
|
1427
|
+
driver_name: t.Optional[str] = None # e.g. "ODBC Driver 18 for SQL Server"
|
|
1428
|
+
trust_server_certificate: t.Optional[bool] = None
|
|
1429
|
+
encrypt: t.Optional[bool] = None
|
|
1430
|
+
# Dictionary of arbitrary ODBC connection properties
|
|
1431
|
+
# See: https://learn.microsoft.com/en-us/sql/connect/odbc/dsn-connection-string-attribute
|
|
1432
|
+
odbc_properties: t.Optional[t.Dict[str, t.Any]] = None
|
|
1433
|
+
|
|
1425
1434
|
concurrent_tasks: int = 4
|
|
1426
1435
|
register_comments: bool = True
|
|
1427
1436
|
pre_ping: bool = True
|
|
1428
1437
|
|
|
1429
1438
|
type_: t.Literal["mssql"] = Field(alias="type", default="mssql")
|
|
1430
1439
|
|
|
1431
|
-
|
|
1440
|
+
@model_validator(mode="before")
|
|
1441
|
+
@classmethod
|
|
1442
|
+
def _mssql_engine_import_validator(cls, data: t.Any) -> t.Any:
|
|
1443
|
+
if not isinstance(data, dict):
|
|
1444
|
+
return data
|
|
1445
|
+
|
|
1446
|
+
driver = data.get("driver", "pymssql")
|
|
1447
|
+
|
|
1448
|
+
# Define the mapping of driver to import module and extra name
|
|
1449
|
+
driver_configs = {"pymssql": ("pymssql", "mssql"), "pyodbc": ("pyodbc", "mssql-odbc")}
|
|
1450
|
+
|
|
1451
|
+
if driver not in driver_configs:
|
|
1452
|
+
raise ValueError(f"Unsupported driver: {driver}")
|
|
1453
|
+
|
|
1454
|
+
import_module, extra_name = driver_configs[driver]
|
|
1455
|
+
|
|
1456
|
+
# Use _get_engine_import_validator with decorate=False to get the raw validation function
|
|
1457
|
+
# This avoids the __wrapped__ issue in Python 3.9
|
|
1458
|
+
validator_func = _get_engine_import_validator(
|
|
1459
|
+
import_module, driver, extra_name, decorate=False
|
|
1460
|
+
)
|
|
1461
|
+
|
|
1462
|
+
# Call the raw validation function directly
|
|
1463
|
+
return validator_func(cls, data)
|
|
1432
1464
|
|
|
1433
1465
|
@property
|
|
1434
1466
|
def _connection_kwargs_keys(self) -> t.Set[str]:
|
|
1435
|
-
|
|
1467
|
+
base_keys = {
|
|
1436
1468
|
"host",
|
|
1437
1469
|
"user",
|
|
1438
1470
|
"password",
|
|
@@ -1447,15 +1479,96 @@ class MSSQLConnectionConfig(ConnectionConfig):
|
|
|
1447
1479
|
"tds_version",
|
|
1448
1480
|
}
|
|
1449
1481
|
|
|
1482
|
+
if self.driver == "pyodbc":
|
|
1483
|
+
base_keys.update(
|
|
1484
|
+
{
|
|
1485
|
+
"driver_name",
|
|
1486
|
+
"trust_server_certificate",
|
|
1487
|
+
"encrypt",
|
|
1488
|
+
"odbc_properties",
|
|
1489
|
+
}
|
|
1490
|
+
)
|
|
1491
|
+
# Remove pymssql-specific parameters
|
|
1492
|
+
base_keys.discard("tds_version")
|
|
1493
|
+
base_keys.discard("conn_properties")
|
|
1494
|
+
|
|
1495
|
+
return base_keys
|
|
1496
|
+
|
|
1450
1497
|
@property
|
|
1451
1498
|
def _engine_adapter(self) -> t.Type[EngineAdapter]:
|
|
1452
1499
|
return engine_adapter.MSSQLEngineAdapter
|
|
1453
1500
|
|
|
1454
1501
|
@property
|
|
1455
1502
|
def _connection_factory(self) -> t.Callable:
|
|
1456
|
-
|
|
1503
|
+
if self.driver == "pymssql":
|
|
1504
|
+
import pymssql
|
|
1505
|
+
|
|
1506
|
+
return pymssql.connect
|
|
1507
|
+
|
|
1508
|
+
import pyodbc
|
|
1509
|
+
|
|
1510
|
+
def connect(**kwargs: t.Any) -> t.Callable:
|
|
1511
|
+
# Extract parameters for connection string
|
|
1512
|
+
host = kwargs.pop("host")
|
|
1513
|
+
port = kwargs.pop("port", 1433)
|
|
1514
|
+
database = kwargs.pop("database", "")
|
|
1515
|
+
user = kwargs.pop("user", None)
|
|
1516
|
+
password = kwargs.pop("password", None)
|
|
1517
|
+
driver_name = kwargs.pop("driver_name", "ODBC Driver 18 for SQL Server")
|
|
1518
|
+
trust_server_certificate = kwargs.pop("trust_server_certificate", False)
|
|
1519
|
+
encrypt = kwargs.pop("encrypt", True)
|
|
1520
|
+
login_timeout = kwargs.pop("login_timeout", 60)
|
|
1521
|
+
|
|
1522
|
+
# Build connection string
|
|
1523
|
+
conn_str_parts = [
|
|
1524
|
+
f"DRIVER={{{driver_name}}}",
|
|
1525
|
+
f"SERVER={host},{port}",
|
|
1526
|
+
]
|
|
1527
|
+
|
|
1528
|
+
if database:
|
|
1529
|
+
conn_str_parts.append(f"DATABASE={database}")
|
|
1530
|
+
|
|
1531
|
+
# Add security options
|
|
1532
|
+
conn_str_parts.append(f"Encrypt={'YES' if encrypt else 'NO'}")
|
|
1533
|
+
if trust_server_certificate:
|
|
1534
|
+
conn_str_parts.append("TrustServerCertificate=YES")
|
|
1535
|
+
|
|
1536
|
+
conn_str_parts.append(f"Connection Timeout={login_timeout}")
|
|
1537
|
+
|
|
1538
|
+
# Standard SQL Server authentication
|
|
1539
|
+
if user:
|
|
1540
|
+
conn_str_parts.append(f"UID={user}")
|
|
1541
|
+
if password:
|
|
1542
|
+
conn_str_parts.append(f"PWD={password}")
|
|
1543
|
+
|
|
1544
|
+
# Add any additional ODBC properties from the odbc_properties dictionary
|
|
1545
|
+
if self.odbc_properties:
|
|
1546
|
+
for key, value in self.odbc_properties.items():
|
|
1547
|
+
# Skip properties that we've already set above
|
|
1548
|
+
if key.lower() in (
|
|
1549
|
+
"driver",
|
|
1550
|
+
"server",
|
|
1551
|
+
"database",
|
|
1552
|
+
"uid",
|
|
1553
|
+
"pwd",
|
|
1554
|
+
"encrypt",
|
|
1555
|
+
"trustservercertificate",
|
|
1556
|
+
"connection timeout",
|
|
1557
|
+
):
|
|
1558
|
+
continue
|
|
1457
1559
|
|
|
1458
|
-
|
|
1560
|
+
# Handle boolean values properly
|
|
1561
|
+
if isinstance(value, bool):
|
|
1562
|
+
conn_str_parts.append(f"{key}={'YES' if value else 'NO'}")
|
|
1563
|
+
else:
|
|
1564
|
+
conn_str_parts.append(f"{key}={value}")
|
|
1565
|
+
|
|
1566
|
+
# Create the connection string
|
|
1567
|
+
conn_str = ";".join(conn_str_parts)
|
|
1568
|
+
|
|
1569
|
+
return pyodbc.connect(conn_str, autocommit=kwargs.get("autocommit", False))
|
|
1570
|
+
|
|
1571
|
+
return connect
|
|
1459
1572
|
|
|
1460
1573
|
@property
|
|
1461
1574
|
def _extra_engine_config(self) -> t.Dict[str, t.Any]:
|
|
@@ -219,6 +219,10 @@ class MSSQLEngineAdapter(
|
|
|
219
219
|
assert isinstance(df, pd.DataFrame)
|
|
220
220
|
temp_table = self._get_temp_table(target_table or "pandas")
|
|
221
221
|
|
|
222
|
+
# Return the superclass implementation if the connection pool doesn't support bulk_copy
|
|
223
|
+
if not hasattr(self._connection_pool.get(), "bulk_copy"):
|
|
224
|
+
return super()._df_to_source_queries(df, columns_to_types, batch_size, target_table)
|
|
225
|
+
|
|
222
226
|
def query_factory() -> Query:
|
|
223
227
|
# It is possible for the factory to be called multiple times and if so then the temp table will already
|
|
224
228
|
# be created so we skip creating again. This means we are assuming the first call is the same result
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlmesh
|
|
3
|
-
Version: 0.191.1.
|
|
3
|
+
Version: 0.191.1.dev2
|
|
4
4
|
Summary: Next-generation data transformation framework
|
|
5
5
|
Author-email: "TobikoData Inc." <engineering@tobikodata.com>
|
|
6
6
|
License: Apache License
|
|
@@ -241,6 +241,8 @@ Provides-Extra: athena
|
|
|
241
241
|
Requires-Dist: PyAthena[Pandas]; extra == "athena"
|
|
242
242
|
Provides-Extra: azuresql
|
|
243
243
|
Requires-Dist: pymssql; extra == "azuresql"
|
|
244
|
+
Provides-Extra: azuresql-odbc
|
|
245
|
+
Requires-Dist: pyodbc; extra == "azuresql-odbc"
|
|
244
246
|
Provides-Extra: bigquery
|
|
245
247
|
Requires-Dist: google-cloud-bigquery[pandas]; extra == "bigquery"
|
|
246
248
|
Requires-Dist: google-cloud-bigquery-storage; extra == "bigquery"
|
|
@@ -311,6 +313,8 @@ Requires-Dist: langchain; extra == "llm"
|
|
|
311
313
|
Requires-Dist: openai; extra == "llm"
|
|
312
314
|
Provides-Extra: mssql
|
|
313
315
|
Requires-Dist: pymssql; extra == "mssql"
|
|
316
|
+
Provides-Extra: mssql-odbc
|
|
317
|
+
Requires-Dist: pyodbc; extra == "mssql-odbc"
|
|
314
318
|
Provides-Extra: mysql
|
|
315
319
|
Requires-Dist: pymysql; extra == "mysql"
|
|
316
320
|
Provides-Extra: mwaa
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
sqlmesh/__init__.py,sha256=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
|
|
2
|
-
sqlmesh/_version.py,sha256=
|
|
2
|
+
sqlmesh/_version.py,sha256=3VcMADjN_hztomDeuXOjOIf8lrB7o5RCIewqH-yhrjE,528
|
|
3
3
|
sqlmesh/magics.py,sha256=gjzoxREb1XT8Yho_PQMlMqhhkLq_sEfBM8S3PTgxvWE,40337
|
|
4
4
|
sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -41,7 +41,7 @@ sqlmesh/core/config/__init__.py,sha256=b4gFb04tpeZpowqJD-7h3U3TLgxrpQhZahVEAo6VW
|
|
|
41
41
|
sqlmesh/core/config/base.py,sha256=t8NQmsgQoZSc-k0dlDiCb8t1jj0AMYdGZ-6se9q_Pks,4898
|
|
42
42
|
sqlmesh/core/config/categorizer.py,sha256=6vzUoNLjR6GOEb_2mYVz2TwmMv2BfldgHX2u-Le5HZs,1975
|
|
43
43
|
sqlmesh/core/config/common.py,sha256=-o_HoRFtR4u84frg_TLno7z7vS9II6ASiOayb59MKHo,2806
|
|
44
|
-
sqlmesh/core/config/connection.py,sha256=
|
|
44
|
+
sqlmesh/core/config/connection.py,sha256=AV7Bx64YCPQCv6J17bsgt-1SyIOAZSEqHIF8U3Nrfh0,82103
|
|
45
45
|
sqlmesh/core/config/feature_flag.py,sha256=JRcD31OG_t2cYc24meKbHDGB0iVID0P07V2oOeB_mgA,203
|
|
46
46
|
sqlmesh/core/config/format.py,sha256=6CXFbvnor56xbldKE-Vrm9k_ABRoY4v6vgIb3mCihiQ,1355
|
|
47
47
|
sqlmesh/core/config/gateway.py,sha256=tYngyqwd_4Qr9lhcv2hlvLvb_2pgYYtKu6hdGsTr-4I,1931
|
|
@@ -66,7 +66,7 @@ sqlmesh/core/engine_adapter/clickhouse.py,sha256=LoPdm_s_s-ZxS1XJPA3Et0iOHeJ1Lgq
|
|
|
66
66
|
sqlmesh/core/engine_adapter/databricks.py,sha256=8ZExPIeT3dDh9MTJW8udvmh9LiY-f9HkRAN1Q5Qebhs,14541
|
|
67
67
|
sqlmesh/core/engine_adapter/duckdb.py,sha256=rFv27sF1KXhJcrIuM9Zdfl2cyZNRXEF9qQczgODdK0M,4614
|
|
68
68
|
sqlmesh/core/engine_adapter/mixins.py,sha256=HMB0Z9O3p5jaTZMolKiWKqpVDZokf5GoI99YXwEJ8bc,22470
|
|
69
|
-
sqlmesh/core/engine_adapter/mssql.py,sha256=
|
|
69
|
+
sqlmesh/core/engine_adapter/mssql.py,sha256=e-PElz8RAUwD-fGCx-2oleg3UGxFH-f0AzXODR3hpm0,14140
|
|
70
70
|
sqlmesh/core/engine_adapter/mysql.py,sha256=lVC-siXZK3iSfqCmBjZNw8uy09Z8la8v8_oUZ-E2OwI,6966
|
|
71
71
|
sqlmesh/core/engine_adapter/postgres.py,sha256=fdQrsBodfGlNf8lZYkS99U_gjoDyaYKEVKLgScduv3I,4601
|
|
72
72
|
sqlmesh/core/engine_adapter/redshift.py,sha256=B4GsPggz-xyvBpx5qubvVwEeKF3vk7n5SMExL-Q5Ysw,16754
|
|
@@ -275,7 +275,7 @@ sqlmesh/utils/pydantic.py,sha256=I898jAFqa3qU6lG2uPpRebVFncOUo8ZrLWM_R3K3DHU,116
|
|
|
275
275
|
sqlmesh/utils/rich.py,sha256=xNZyPCqEc4TAlJlsEthg-5eYUWpaizz0QjBzO7a1Yv4,1509
|
|
276
276
|
sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
|
|
277
277
|
sqlmesh/utils/yaml.py,sha256=np-WVcwmwsKghCgAj1OBBMsK1SXSRn4wR-H37cGiFr8,2282
|
|
278
|
-
sqlmesh-0.191.1.
|
|
278
|
+
sqlmesh-0.191.1.dev2.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
|
|
279
279
|
web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
280
280
|
web/client/dist/index.html,sha256=k5bAEoPDJ0BhYQ4hBcKWObITCxIgqOUC28nGXvEDrt0,5472
|
|
281
281
|
web/client/dist/assets/Audits-Pgs8N6IE.js,sha256=BQuc9kiznZSqTnzNrJSDNqAAdOTGjNQJt32M1sHZFok,1041
|
|
@@ -393,8 +393,8 @@ web/server/api/endpoints/models.py,sha256=ud-lRwriyI_OYg9tZchrBgeiXELiRTLNEodraf
|
|
|
393
393
|
web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
|
|
394
394
|
web/server/api/endpoints/plan.py,sha256=OYuQ_4dgbhG9ibTcX1a8mvYgH3ANxw9Fhbb4wg6QWqc,9222
|
|
395
395
|
web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
|
|
396
|
-
sqlmesh-0.191.1.
|
|
397
|
-
sqlmesh-0.191.1.
|
|
398
|
-
sqlmesh-0.191.1.
|
|
399
|
-
sqlmesh-0.191.1.
|
|
400
|
-
sqlmesh-0.191.1.
|
|
396
|
+
sqlmesh-0.191.1.dev2.dist-info/METADATA,sha256=4VXVPffRoDSY07wCfBSu04NbrRdUV7FELjwuCNKSufQ,26690
|
|
397
|
+
sqlmesh-0.191.1.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
398
|
+
sqlmesh-0.191.1.dev2.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
|
|
399
|
+
sqlmesh-0.191.1.dev2.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
|
|
400
|
+
sqlmesh-0.191.1.dev2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|