sqlmesh 0.184.4.dev2__py3-none-any.whl → 0.184.4.dev4__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 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.184.4.dev2'
21
- __version_tuple__ = version_tuple = (0, 184, 4, 'dev2')
20
+ __version__ = version = '0.184.4.dev4'
21
+ __version_tuple__ = version_tuple = (0, 184, 4, 'dev4')
@@ -13,6 +13,7 @@ from functools import partial
13
13
 
14
14
  import pydantic
15
15
  from pydantic import Field
16
+ from packaging import version
16
17
  from sqlglot import exp
17
18
  from sqlglot.helper import subclasses
18
19
 
@@ -201,6 +202,7 @@ class BaseDuckDBConnectionConfig(ConnectionConfig):
201
202
  catalogs: Key is the name of the catalog and value is the path.
202
203
  extensions: A list of autoloadable extensions to load.
203
204
  connector_config: A dictionary of configuration to pass into the duckdb connector.
205
+ secrets: A list of dictionaries used to generate DuckDB secrets for authenticating with external services (e.g. S3).
204
206
  concurrent_tasks: The maximum number of tasks that can use this connection concurrently.
205
207
  register_comments: Whether or not to register model comments with the SQL engine.
206
208
  pre_ping: Whether or not to pre-ping the connection before starting a new transaction to ensure it is still alive.
@@ -211,6 +213,7 @@ class BaseDuckDBConnectionConfig(ConnectionConfig):
211
213
  catalogs: t.Optional[t.Dict[str, t.Union[str, DuckDBAttachOptions]]] = None
212
214
  extensions: t.List[t.Union[str, t.Dict[str, t.Any]]] = []
213
215
  connector_config: t.Dict[str, t.Any] = {}
216
+ secrets: t.List[t.Dict[str, t.Any]] = []
214
217
 
215
218
  concurrent_tasks: int = 1
216
219
  register_comments: bool = True
@@ -283,6 +286,28 @@ class BaseDuckDBConnectionConfig(ConnectionConfig):
283
286
  except Exception as e:
284
287
  raise ConfigError(f"Failed to set connector config {field} to {setting}: {e}")
285
288
 
289
+ if self.secrets:
290
+ duckdb_version = duckdb.__version__
291
+ if version.parse(duckdb_version) < version.parse("0.10.0"):
292
+ from sqlmesh.core.console import get_console
293
+
294
+ get_console().log_warning(
295
+ f"DuckDB version {duckdb_version} does not support secrets-based authentication (requires 0.10.0 or later).\n"
296
+ "To use secrets, please upgrade DuckDB. For older versions, configure legacy authentication via `connector_config`.\n"
297
+ "More info: https://duckdb.org/docs/stable/extensions/httpfs/s3api_legacy_authentication.html"
298
+ )
299
+ else:
300
+ for secrets in self.secrets:
301
+ secret_settings: t.List[str] = []
302
+ for field, setting in secrets.items():
303
+ secret_settings.append(f"{field} '{setting}'")
304
+ if secret_settings:
305
+ secret_clause = ", ".join(secret_settings)
306
+ try:
307
+ cursor.execute(f"CREATE SECRET ({secret_clause});")
308
+ except Exception as e:
309
+ raise ConfigError(f"Failed to create secret: {e}")
310
+
286
311
  for i, (alias, path_options) in enumerate(
287
312
  (getattr(self, "catalogs", None) or {}).items()
288
313
  ):
@@ -106,6 +106,7 @@ class EngineAdapter:
106
106
  SUPPORTS_REPLACE_TABLE = True
107
107
  DEFAULT_CATALOG_TYPE = DIALECT
108
108
  QUOTE_IDENTIFIERS_IN_VIEWS = True
109
+ MAX_IDENTIFIER_LENGTH: t.Optional[int] = None
109
110
 
110
111
  def __init__(
111
112
  self,
@@ -2138,14 +2139,12 @@ class EngineAdapter:
2138
2139
  )
2139
2140
  with self.transaction():
2140
2141
  for e in ensure_list(expressions):
2141
- sql = t.cast(
2142
- str,
2143
- (
2144
- self._to_sql(e, quote=quote_identifiers, **to_sql_kwargs)
2145
- if isinstance(e, exp.Expression)
2146
- else e
2147
- ),
2148
- )
2142
+ if isinstance(e, exp.Expression):
2143
+ self._check_identifier_length(e)
2144
+ sql = self._to_sql(e, quote=quote_identifiers, **to_sql_kwargs)
2145
+ else:
2146
+ sql = t.cast(str, e)
2147
+
2149
2148
  self._log_sql(
2150
2149
  sql,
2151
2150
  expression=e if isinstance(e, exp.Expression) else None,
@@ -2516,6 +2515,18 @@ class EngineAdapter:
2516
2515
  def _select_columns(cls, columns: t.Iterable[str]) -> exp.Select:
2517
2516
  return exp.select(*(exp.column(c, quoted=True) for c in columns))
2518
2517
 
2518
+ def _check_identifier_length(self, expression: exp.Expression) -> None:
2519
+ if self.MAX_IDENTIFIER_LENGTH is None or not isinstance(expression, exp.DDL):
2520
+ return
2521
+
2522
+ for identifier in expression.find_all(exp.Identifier):
2523
+ name = identifier.name
2524
+ name_length = len(name)
2525
+ if name_length > self.MAX_IDENTIFIER_LENGTH:
2526
+ raise SQLMeshError(
2527
+ f"Identifier name '{name}' (length {name_length}) exceeds {self.dialect.capitalize()}'s max identifier limit of {self.MAX_IDENTIFIER_LENGTH} characters"
2528
+ )
2529
+
2519
2530
 
2520
2531
  class EngineAdapterWithIndexSupport(EngineAdapter):
2521
2532
  SUPPORTS_INDEXES = True
@@ -39,6 +39,7 @@ class MySQLEngineAdapter(
39
39
  MAX_TABLE_COMMENT_LENGTH = 2048
40
40
  MAX_COLUMN_COMMENT_LENGTH = 1024
41
41
  SUPPORTS_REPLACE_TABLE = False
42
+ MAX_IDENTIFIER_LENGTH = 64
42
43
  SCHEMA_DIFFER = SchemaDiffer(
43
44
  parameterized_type_defaults={
44
45
  exp.DataType.build("BIT", dialect=DIALECT).this: [(1,)],
@@ -34,6 +34,7 @@ class PostgresEngineAdapter(
34
34
  HAS_VIEW_BINDING = True
35
35
  CURRENT_CATALOG_EXPRESSION = exp.column("current_catalog")
36
36
  SUPPORTS_REPLACE_TABLE = False
37
+ MAX_IDENTIFIER_LENGTH = 63
37
38
  SCHEMA_DIFFER = SchemaDiffer(
38
39
  parameterized_type_defaults={
39
40
  # DECIMAL without precision is "up to 131072 digits before the decimal point; up to 16383 digits after the decimal point"
@@ -30,6 +30,7 @@ class RisingwaveEngineAdapter(PostgresEngineAdapter):
30
30
  COMMENT_CREATION_VIEW = CommentCreationView.UNSUPPORTED
31
31
  SUPPORTS_MATERIALIZED_VIEWS = True
32
32
  SUPPORTS_TRANSACTIONS = False
33
+ MAX_IDENTIFIER_LENGTH = None
33
34
 
34
35
  def _truncate_table(self, table_name: TableName) -> None:
35
36
  return self.execute(exp.Delete(this=exp.to_table(table_name)))
sqlmesh/dbt/target.py CHANGED
@@ -151,6 +151,7 @@ class DuckDbConfig(TargetConfig):
151
151
  path: Location of the database file. If not specified, an in memory database is used.
152
152
  extensions: A list of autoloadable extensions to load.
153
153
  settings: A dictionary of settings to pass into the duckdb connector.
154
+ secrets: A list of secrets to pass to the secret manager in the duckdb connector.
154
155
  """
155
156
 
156
157
  type: t.Literal["duckdb"] = "duckdb"
@@ -159,6 +160,7 @@ class DuckDbConfig(TargetConfig):
159
160
  path: str = DUCKDB_IN_MEMORY
160
161
  extensions: t.Optional[t.List[str]] = None
161
162
  settings: t.Optional[t.Dict[str, t.Any]] = None
163
+ secrets: t.Optional[t.List[t.Dict[str, t.Any]]] = None
162
164
 
163
165
  @model_validator(mode="before")
164
166
  def validate_authentication(cls, data: t.Any) -> t.Any:
@@ -192,6 +194,8 @@ class DuckDbConfig(TargetConfig):
192
194
  kwargs["extensions"] = self.extensions
193
195
  if self.settings is not None:
194
196
  kwargs["connector_config"] = self.settings
197
+ if self.secrets is not None:
198
+ kwargs["secrets"] = self.secrets
195
199
  return DuckDBConnectionConfig(
196
200
  database=self.path,
197
201
  concurrent_tasks=1,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.184.4.dev2
3
+ Version: 0.184.4.dev4
4
4
  Summary: Next-generation data transformation framework
5
5
  Author-email: "TobikoData Inc." <engineering@tobikodata.com>
6
6
  License: Apache License
@@ -1,5 +1,5 @@
1
1
  sqlmesh/__init__.py,sha256=DRovDXI-9D9xeYDP7t8Fq7mI31S2btlN-LHPOK3y7PA,7240
2
- sqlmesh/_version.py,sha256=wQuD5_QObpaHiyQWgdojLHW571NIDF9meJc6Ge5ITBI,528
2
+ sqlmesh/_version.py,sha256=ifVqs-FEUDrnjUcfvVbgyQx7o0Vun52nDVXWHD0E3wI,528
3
3
  sqlmesh/magics.py,sha256=aeOyTdeNnyGzGtJXECDAbqJ8OAplrV4UAYl0I2hhtig,39670
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=kMhHzIKAIz2uiM5XhRgn-yMUOVS1B_aJEmIejGnUClo,71976
44
+ sqlmesh/core/config/connection.py,sha256=2xEBZFjaHgdTiSj0MjDIfCPnOoe5dT4gRQ2RYm0bQ80,73499
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
@@ -59,7 +59,7 @@ sqlmesh/core/config/ui.py,sha256=jsO-S6_d9NkLZGG5pT4mgKgxMF34KzkDociZAMvCX3U,278
59
59
  sqlmesh/core/engine_adapter/__init__.py,sha256=two_WTs4UnSNp-fscJh8vOunJq0Xi37EuDuMjKsKuNE,2281
60
60
  sqlmesh/core/engine_adapter/_typing.py,sha256=BAM_U7Vsi0k37XHu_nNnu3whXxuTVDey_uZe3aelKYY,1033
61
61
  sqlmesh/core/engine_adapter/athena.py,sha256=WBVAB_YzBJXdiqq51LTd2jmYoMtGrLmtsA8IrIFVnQ0,26199
62
- sqlmesh/core/engine_adapter/base.py,sha256=XQeJi4Rr5VllnQKFZBYXNs1G142T16ZOVU_l9UYvzoE,100539
62
+ sqlmesh/core/engine_adapter/base.py,sha256=WDyZhieFq9iBQSDsLdf-ae6aPu25d-FpwZ4Lt3FPf6o,101153
63
63
  sqlmesh/core/engine_adapter/base_postgres.py,sha256=DOsOdCJyQAVfA9S0GznuH0J1bonMqYVP_yJLDYcxFYM,6772
64
64
  sqlmesh/core/engine_adapter/bigquery.py,sha256=gnd2cFc7v95tT_E9XMHHgccS-QwSF2sJHsL8xfcSguk,49249
65
65
  sqlmesh/core/engine_adapter/clickhouse.py,sha256=4ACsYsZ8-gvyCozwoEMEayTTUdMjmNea4xUkxtXw6R4,34907
@@ -67,10 +67,10 @@ sqlmesh/core/engine_adapter/databricks.py,sha256=AbNbnt9nQdOd7lTov2zsKROZlzgV2fL
67
67
  sqlmesh/core/engine_adapter/duckdb.py,sha256=FfNmBzLySDDi--nTlsSavTwdperCzhpYzDoroCilPcA,4900
68
68
  sqlmesh/core/engine_adapter/mixins.py,sha256=HMB0Z9O3p5jaTZMolKiWKqpVDZokf5GoI99YXwEJ8bc,22470
69
69
  sqlmesh/core/engine_adapter/mssql.py,sha256=N21kjLrvloxLPMCGloQx5Jew5SIddrCVq3lTrnl8coc,11788
70
- sqlmesh/core/engine_adapter/mysql.py,sha256=HnMtNjxnCVz3X3-uK8Im-BNgLo_viX6QH3Uo8rMfPeY,6935
71
- sqlmesh/core/engine_adapter/postgres.py,sha256=XWnV7MDndkCRokb7ih2yxXodw4W8E61yHbuWtRTFE3k,4570
70
+ sqlmesh/core/engine_adapter/mysql.py,sha256=lVC-siXZK3iSfqCmBjZNw8uy09Z8la8v8_oUZ-E2OwI,6966
71
+ sqlmesh/core/engine_adapter/postgres.py,sha256=fdQrsBodfGlNf8lZYkS99U_gjoDyaYKEVKLgScduv3I,4601
72
72
  sqlmesh/core/engine_adapter/redshift.py,sha256=_rZWv4rchDAzB6m6idoV1NLHFBKK_gM4nlfeErqXEcE,16691
73
- sqlmesh/core/engine_adapter/risingwave.py,sha256=NXXuiPfbB5ZSp7igMqZpaX2c-5TYreOlIouPU7iCVJ8,936
73
+ sqlmesh/core/engine_adapter/risingwave.py,sha256=YYCQ0EJaSrR9_P1_2_LmElQ6zSxqkZzhvhdm-2WtWWg,969
74
74
  sqlmesh/core/engine_adapter/shared.py,sha256=NyF2osSJDWPp7KlJUBR4GZcS_cJFr4daUPvhGyp4XcQ,12909
75
75
  sqlmesh/core/engine_adapter/snowflake.py,sha256=gxZWDOY12itwVWF6anqyZI6bXnaK2wY3Uca0qnH5ffk,27142
76
76
  sqlmesh/core/engine_adapter/spark.py,sha256=nDJXH1su08wv3m9X0Mz-x98xhZblq1BvM3EtRYjZhrI,21012
@@ -136,7 +136,7 @@ sqlmesh/dbt/project.py,sha256=4PJHPVWIKDd71J5__iICqEp21nFiijKjJkiE5kZIH5Y,3980
136
136
  sqlmesh/dbt/relation.py,sha256=3w_4_Dj-oZXUEdBqOl9U6twbt8S2gDNMaFRb3unqkE8,224
137
137
  sqlmesh/dbt/seed.py,sha256=E7pFhtGwRrC9U_VZJNABwLTa-Nk4OeD-gOtjSpvYmDA,4251
138
138
  sqlmesh/dbt/source.py,sha256=IZK-aOV-KdWIOPuXqRjJZAZ7phW1HUXoHtE-3clgkx4,4125
139
- sqlmesh/dbt/target.py,sha256=18jn-BmRO4oR9w-R1_y1RGhQyvzQD9HPu0r8gwJaivI,40298
139
+ sqlmesh/dbt/target.py,sha256=YFCqQPhPcMa_7chMoKTTwIYEqaERlDvNipEGPw2RmM4,40529
140
140
  sqlmesh/dbt/test.py,sha256=aOTKqYpVafff-TU4Xhbc9eZr6QAuFLMxIu_sV-18JLQ,8282
141
141
  sqlmesh/dbt/util.py,sha256=uDFgAXBRFTHNVLJdNhMASqOURe_1OH132AD97sMjj1E,774
142
142
  sqlmesh/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -268,7 +268,7 @@ sqlmesh/utils/pydantic.py,sha256=-u69PDY-4FLR7ODNKBoN7PsPNmZ0wdhsJcCAG2P6vyY,110
268
268
  sqlmesh/utils/rich.py,sha256=xNZyPCqEc4TAlJlsEthg-5eYUWpaizz0QjBzO7a1Yv4,1509
269
269
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
270
270
  sqlmesh/utils/yaml.py,sha256=np-WVcwmwsKghCgAj1OBBMsK1SXSRn4wR-H37cGiFr8,2282
271
- sqlmesh-0.184.4.dev2.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
271
+ sqlmesh-0.184.4.dev4.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
272
272
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
273
273
  web/client/dist/index.html,sha256=x9qfdHkVkXOwWRFRCZGaixiLj5e9tOQsCDRR92vW9QI,5472
274
274
  web/client/dist/assets/Audits-cGDtiiKB.js,sha256=jrS4x1nQ8Klx67744_LjNI2oBOI9XnnygDR-0wmlme8,1041
@@ -386,8 +386,8 @@ web/server/api/endpoints/models.py,sha256=ud-lRwriyI_OYg9tZchrBgeiXELiRTLNEodraf
386
386
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
387
387
  web/server/api/endpoints/plan.py,sha256=OYuQ_4dgbhG9ibTcX1a8mvYgH3ANxw9Fhbb4wg6QWqc,9222
388
388
  web/server/api/endpoints/table_diff.py,sha256=Wd5YxeKbZB7AkrDvqFgvV9ZQlnKYOF1n5W_w2EHE_Zw,2085
389
- sqlmesh-0.184.4.dev2.dist-info/METADATA,sha256=s_ub4vftL-EKckwWIHPNKy72z0qsjlz97GRBoa-yhz8,25498
390
- sqlmesh-0.184.4.dev2.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
391
- sqlmesh-0.184.4.dev2.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
392
- sqlmesh-0.184.4.dev2.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
393
- sqlmesh-0.184.4.dev2.dist-info/RECORD,,
389
+ sqlmesh-0.184.4.dev4.dist-info/METADATA,sha256=XyejHBbOyFdij3c1e0wMllTRrHkSJVfCJGVXPYMEh9A,25498
390
+ sqlmesh-0.184.4.dev4.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
391
+ sqlmesh-0.184.4.dev4.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
392
+ sqlmesh-0.184.4.dev4.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
393
+ sqlmesh-0.184.4.dev4.dist-info/RECORD,,