sqlmesh 0.204.1.dev4__py3-none-any.whl → 0.204.1.dev6__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.204.1.dev4'
21
- __version_tuple__ = version_tuple = (0, 204, 1, 'dev4')
20
+ __version__ = version = '0.204.1.dev6'
21
+ __version_tuple__ = version_tuple = (0, 204, 1, 'dev6')
@@ -2,7 +2,10 @@ from sqlmesh.core.config.categorizer import (
2
2
  AutoCategorizationMode as AutoCategorizationMode,
3
3
  CategorizerConfig as CategorizerConfig,
4
4
  )
5
- from sqlmesh.core.config.common import EnvironmentSuffixTarget as EnvironmentSuffixTarget
5
+ from sqlmesh.core.config.common import (
6
+ EnvironmentSuffixTarget as EnvironmentSuffixTarget,
7
+ TableNamingConvention as TableNamingConvention,
8
+ )
6
9
  from sqlmesh.core.config.connection import (
7
10
  AthenaConnectionConfig as AthenaConnectionConfig,
8
11
  BaseDuckDBConnectionConfig as BaseDuckDBConnectionConfig,
@@ -49,6 +49,34 @@ class EnvironmentSuffixTarget(str, Enum):
49
49
  return str(self)
50
50
 
51
51
 
52
+ class TableNamingConvention(str, Enum):
53
+ # Causes table names at the physical layer to follow the convention:
54
+ # <schema-name>__<table-name>__<fingerprint>
55
+ SCHEMA_AND_TABLE = "schema_and_table"
56
+
57
+ # Causes table names at the physical layer to follow the convention:
58
+ # <table-name>__<fingerprint>
59
+ TABLE_ONLY = "table_only"
60
+
61
+ # Takes the table name that would be returned from SCHEMA_AND_TABLE and wraps it in md5()
62
+ # to generate a hash and prefixes the has with `sqlmesh_md5__`, for the following reasons:
63
+ # - at a glance, you can still see it's managed by sqlmesh and that md5 was used to generate the hash
64
+ # - unquoted identifiers that start with numbers can trip up DB engine parsers, so having a text prefix prevents this
65
+ # This causes table names at the physical layer to follow the convention:
66
+ # sqlmesh_md5__3b07384d113edec49eaa6238ad5ff00d
67
+ HASH_MD5 = "hash_md5"
68
+
69
+ @classproperty
70
+ def default(cls) -> TableNamingConvention:
71
+ return TableNamingConvention.SCHEMA_AND_TABLE
72
+
73
+ def __str__(self) -> str:
74
+ return self.name
75
+
76
+ def __repr__(self) -> str:
77
+ return str(self)
78
+
79
+
52
80
  def _concurrent_tasks_validator(v: t.Any) -> int:
53
81
  if isinstance(v, str):
54
82
  v = int(v)
@@ -14,7 +14,7 @@ from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
14
14
  from sqlmesh.cicd.config import CICDBotConfig
15
15
  from sqlmesh.core import constants as c
16
16
  from sqlmesh.core.console import get_console
17
- from sqlmesh.core.config import EnvironmentSuffixTarget
17
+ from sqlmesh.core.config import EnvironmentSuffixTarget, TableNamingConvention
18
18
  from sqlmesh.core.config.base import BaseConfig, UpdateStrategy
19
19
  from sqlmesh.core.config.common import variables_validator, compile_regex_mapping
20
20
  from sqlmesh.core.config.connection import (
@@ -106,6 +106,7 @@ class Config(BaseConfig):
106
106
  model_defaults: Default values for model definitions.
107
107
  physical_schema_mapping: A mapping from regular expressions to names of schemas in which physical tables for corresponding models will be placed.
108
108
  environment_suffix_target: Indicates whether to append the environment name to the schema or table name.
109
+ physical_table_naming_convention: Indicates how tables should be named at the physical layer
109
110
  gateway_managed_virtual_layer: Whether the models' views in the virtual layer are created by the model-specific gateway rather than the default gateway.
110
111
  infer_python_dependencies: Whether to statically analyze Python code to automatically infer Python package requirements.
111
112
  environment_catalog_mapping: A mapping from regular expressions to catalog names. The catalog name is used to determine the target catalog for a given environment.
@@ -147,6 +148,9 @@ class Config(BaseConfig):
147
148
  environment_suffix_target: EnvironmentSuffixTarget = Field(
148
149
  default=EnvironmentSuffixTarget.default
149
150
  )
151
+ physical_table_naming_convention: TableNamingConvention = Field(
152
+ default=TableNamingConvention.default
153
+ )
150
154
  gateway_managed_virtual_layer: bool = False
151
155
  infer_python_dependencies: bool = True
152
156
  environment_catalog_mapping: RegexKeyDict = {}
sqlmesh/core/context.py CHANGED
@@ -2904,9 +2904,11 @@ class GenericContext(BaseContext, t.Generic[C]):
2904
2904
  fingerprint_cache: t.Dict[str, SnapshotFingerprint] = {}
2905
2905
 
2906
2906
  for node in nodes.values():
2907
- kwargs = {}
2907
+ kwargs: t.Dict[str, t.Any] = {}
2908
2908
  if node.project in self._projects:
2909
- kwargs["ttl"] = self.config_for_node(node).snapshot_ttl
2909
+ config = self.config_for_node(node)
2910
+ kwargs["ttl"] = config.snapshot_ttl
2911
+ kwargs["table_naming_convention"] = config.physical_table_naming_convention
2910
2912
 
2911
2913
  snapshot = Snapshot.from_node(
2912
2914
  node,
@@ -13,6 +13,7 @@ from pydantic import Field
13
13
  from sqlglot import exp
14
14
  from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
15
15
 
16
+ from sqlmesh.core.config import TableNamingConvention
16
17
  from sqlmesh.core import constants as c
17
18
  from sqlmesh.core.audit import StandaloneAudit
18
19
  from sqlmesh.core.environment import EnvironmentSuffixTarget
@@ -44,7 +45,7 @@ from sqlmesh.utils.metaprogramming import (
44
45
  format_evaluated_code_exception,
45
46
  Executable,
46
47
  )
47
- from sqlmesh.utils.hashing import hash_data
48
+ from sqlmesh.utils.hashing import hash_data, md5
48
49
  from sqlmesh.utils.pydantic import PydanticModel, field_validator
49
50
 
50
51
  if t.TYPE_CHECKING:
@@ -227,6 +228,7 @@ class SnapshotDataVersion(PydanticModel, frozen=True):
227
228
  change_category: t.Optional[SnapshotChangeCategory] = None
228
229
  physical_schema_: t.Optional[str] = Field(default=None, alias="physical_schema")
229
230
  dev_table_suffix: str
231
+ table_naming_convention: TableNamingConvention = Field(default=TableNamingConvention.default)
230
232
 
231
233
  def snapshot_id(self, name: str) -> SnapshotId:
232
234
  return SnapshotId(name=name, identifier=self.fingerprint.to_identifier())
@@ -333,6 +335,7 @@ class SnapshotInfoMixin(ModelKindMixin):
333
335
  # This can be removed from this model once Pydantic 1 support is dropped (must remain in `Snapshot` though)
334
336
  base_table_name_override: t.Optional[str]
335
337
  dev_table_suffix: str
338
+ table_naming_convention: TableNamingConvention = Field(default=TableNamingConvention.default)
336
339
 
337
340
  @cached_property
338
341
  def identifier(self) -> str:
@@ -451,6 +454,7 @@ class SnapshotInfoMixin(ModelKindMixin):
451
454
  version,
452
455
  catalog=self.fully_qualified_table.catalog,
453
456
  suffix=self.dev_table_suffix if is_dev_table else None,
457
+ naming_convention=self.table_naming_convention,
454
458
  )
455
459
 
456
460
  @property
@@ -580,6 +584,7 @@ class Snapshot(PydanticModel, SnapshotInfoMixin):
580
584
  migrated: Whether or not this snapshot has been created as a result of migration.
581
585
  unrestorable: Whether or not this snapshot can be used to revert its model to a previous version.
582
586
  next_auto_restatement_ts: The timestamp which indicates when is the next time this snapshot should be restated.
587
+ table_naming_convention: Convention to follow when generating the physical table name
583
588
  """
584
589
 
585
590
  name: str
@@ -605,6 +610,9 @@ class Snapshot(PydanticModel, SnapshotInfoMixin):
605
610
  base_table_name_override: t.Optional[str] = None
606
611
  next_auto_restatement_ts: t.Optional[int] = None
607
612
  dev_table_suffix: str = "dev"
613
+ table_naming_convention_: TableNamingConvention = Field(
614
+ default=TableNamingConvention.default, alias="table_naming_convention"
615
+ )
608
616
 
609
617
  @field_validator("ttl")
610
618
  @classmethod
@@ -656,6 +664,7 @@ class Snapshot(PydanticModel, SnapshotInfoMixin):
656
664
  ttl: str = c.DEFAULT_SNAPSHOT_TTL,
657
665
  version: t.Optional[str] = None,
658
666
  cache: t.Optional[t.Dict[str, SnapshotFingerprint]] = None,
667
+ table_naming_convention: TableNamingConvention = TableNamingConvention.default,
659
668
  ) -> Snapshot:
660
669
  """Creates a new snapshot for a node.
661
670
 
@@ -666,6 +675,7 @@ class Snapshot(PydanticModel, SnapshotInfoMixin):
666
675
  ttl: A TTL to determine how long orphaned (snapshots that are not promoted anywhere) should live.
667
676
  version: The version that a snapshot is associated with. Usually set during the planning phase.
668
677
  cache: Cache of node name to fingerprints.
678
+ table_naming_convention: Convention to follow when generating the physical table name
669
679
 
670
680
  Returns:
671
681
  The newly created snapshot.
@@ -697,6 +707,7 @@ class Snapshot(PydanticModel, SnapshotInfoMixin):
697
707
  updated_ts=created_ts,
698
708
  ttl=ttl,
699
709
  version=version,
710
+ table_naming_convention=table_naming_convention,
700
711
  )
701
712
 
702
713
  def __eq__(self, other: t.Any) -> bool:
@@ -1013,6 +1024,7 @@ class Snapshot(PydanticModel, SnapshotInfoMixin):
1013
1024
  previous_version = self.previous_version
1014
1025
  self.version = previous_version.data_version.version
1015
1026
  self.physical_schema_ = previous_version.physical_schema
1027
+ self.table_naming_convention = previous_version.table_naming_convention
1016
1028
  if self.is_materialized and (category.is_indirect_non_breaking or category.is_metadata):
1017
1029
  # Reuse the dev table for indirect non-breaking changes.
1018
1030
  self.dev_version_ = (
@@ -1206,6 +1218,7 @@ class Snapshot(PydanticModel, SnapshotInfoMixin):
1206
1218
  custom_materialization=custom_materialization,
1207
1219
  dev_table_suffix=self.dev_table_suffix,
1208
1220
  model_gateway=self.model_gateway,
1221
+ table_naming_convention=self.table_naming_convention, # type: ignore
1209
1222
  )
1210
1223
 
1211
1224
  @property
@@ -1218,6 +1231,7 @@ class Snapshot(PydanticModel, SnapshotInfoMixin):
1218
1231
  change_category=self.change_category,
1219
1232
  physical_schema=self.physical_schema,
1220
1233
  dev_table_suffix=self.dev_table_suffix,
1234
+ table_naming_convention=self.table_naming_convention,
1221
1235
  )
1222
1236
 
1223
1237
  @property
@@ -1568,14 +1582,41 @@ def table_name(
1568
1582
  version: str,
1569
1583
  catalog: t.Optional[str] = None,
1570
1584
  suffix: t.Optional[str] = None,
1585
+ naming_convention: t.Optional[TableNamingConvention] = None,
1571
1586
  ) -> str:
1572
1587
  table = exp.to_table(name)
1573
1588
 
1574
- # bigquery projects usually have "-" in them which is illegal in the table name, so we aggressively prune
1575
- name = "__".join(sanitize_name(part.name) for part in table.parts)
1589
+ naming_convention = naming_convention or TableNamingConvention.default
1590
+
1591
+ if naming_convention == TableNamingConvention.HASH_MD5:
1592
+ # just take a MD5 hash of what we would have generated anyway using SCHEMA_AND_TABLE
1593
+ value_to_hash = table_name(
1594
+ physical_schema=physical_schema,
1595
+ name=name,
1596
+ version=version,
1597
+ catalog=catalog,
1598
+ suffix=suffix,
1599
+ naming_convention=TableNamingConvention.SCHEMA_AND_TABLE,
1600
+ )
1601
+ full_name = f"{c.SQLMESH}_md5__{md5(value_to_hash)}"
1602
+ else:
1603
+ # note: Snapshot._table_name() already strips the catalog from the model name before calling this function
1604
+ # Therefore, a model with 3-part naming like "foo.bar.baz" gets passed as (name="bar.baz", catalog="foo") to this function
1605
+ # This is why there is no TableNamingConvention.CATALOG_AND_SCHEMA_AND_TABLE
1606
+ table_parts = table.parts
1607
+ parts_to_consider = 2 if naming_convention == TableNamingConvention.SCHEMA_AND_TABLE else 1
1608
+
1609
+ # in case the parsed table name has less parts than what the naming convention says we should be considering
1610
+ parts_to_consider = min(len(table_parts), parts_to_consider)
1611
+
1612
+ # bigquery projects usually have "-" in them which is illegal in the table name, so we aggressively prune
1613
+ name = "__".join(sanitize_name(part.name) for part in table_parts[-parts_to_consider:])
1614
+
1615
+ full_name = f"{name}__{version}"
1616
+
1576
1617
  suffix = f"__{suffix}" if suffix else ""
1577
1618
 
1578
- table.set("this", exp.to_identifier(f"{name}__{version}{suffix}"))
1619
+ table.set("this", exp.to_identifier(f"{full_name}{suffix}"))
1579
1620
  table.set("db", exp.to_identifier(physical_schema))
1580
1621
  if not table.catalog and catalog:
1581
1622
  table.set("catalog", exp.to_identifier(catalog))
sqlmesh/lsp/main.py CHANGED
@@ -496,10 +496,10 @@ class SQLMeshLanguageServer:
496
496
  target_range = reference.target_range
497
497
  target_selection_range = reference.target_range
498
498
 
499
- if reference.uri is not None:
499
+ if reference.path is not None:
500
500
  location_links.append(
501
501
  types.LocationLink(
502
- target_uri=reference.uri,
502
+ target_uri=URI.from_path(reference.path).value,
503
503
  target_selection_range=target_selection_range,
504
504
  target_range=target_range,
505
505
  origin_selection_range=reference.range,
@@ -523,9 +523,9 @@ class SQLMeshLanguageServer:
523
523
 
524
524
  # Convert references to Location objects
525
525
  locations = [
526
- types.Location(uri=ref.uri, range=ref.range)
526
+ types.Location(uri=URI.from_path(ref.path).value, range=ref.range)
527
527
  for ref in all_references
528
- if ref.uri is not None
528
+ if ref.path is not None
529
529
  ]
530
530
 
531
531
  return locations if locations else None
sqlmesh/lsp/reference.py CHANGED
@@ -29,7 +29,7 @@ class LSPModelReference(PydanticModel):
29
29
  """A LSP reference to a model, excluding external models."""
30
30
 
31
31
  type: t.Literal["model"] = "model"
32
- uri: str
32
+ path: Path
33
33
  range: Range
34
34
  markdown_description: t.Optional[str] = None
35
35
 
@@ -40,9 +40,9 @@ class LSPExternalModelReference(PydanticModel):
40
40
  type: t.Literal["external_model"] = "external_model"
41
41
  range: Range
42
42
  target_range: t.Optional[Range] = None
43
- uri: t.Optional[str] = None
44
- """The URI of the external model, typically a YAML file, it is optional because
45
- external models can be unregistered and so they URI is not available."""
43
+ path: t.Optional[Path] = None
44
+ """The path of the external model, typically a YAML file, it is optional because
45
+ external models can be unregistered and so the path is not available."""
46
46
 
47
47
  markdown_description: t.Optional[str] = None
48
48
 
@@ -51,7 +51,7 @@ class LSPCteReference(PydanticModel):
51
51
  """A LSP reference to a CTE."""
52
52
 
53
53
  type: t.Literal["cte"] = "cte"
54
- uri: str
54
+ path: Path
55
55
  range: Range
56
56
  target_range: Range
57
57
 
@@ -60,7 +60,7 @@ class LSPMacroReference(PydanticModel):
60
60
  """A LSP reference to a macro."""
61
61
 
62
62
  type: t.Literal["macro"] = "macro"
63
- uri: str
63
+ path: Path
64
64
  range: Range
65
65
  target_range: Range
66
66
  markdown_description: t.Optional[str] = None
@@ -209,7 +209,7 @@ def get_model_definitions_for_a_path(
209
209
 
210
210
  references.append(
211
211
  LSPCteReference(
212
- uri=document_uri.value, # Same file
212
+ path=document_uri.to_path(), # Same file
213
213
  range=table_range,
214
214
  target_range=target_range,
215
215
  )
@@ -219,7 +219,7 @@ def get_model_definitions_for_a_path(
219
219
  scope=scope,
220
220
  reference_name=table.name,
221
221
  read_file=read_file,
222
- referenced_model_uri=document_uri,
222
+ referenced_model_path=document_uri.to_path(),
223
223
  description="",
224
224
  reference_type="cte",
225
225
  cte_target_range=target_range,
@@ -270,7 +270,6 @@ def get_model_definitions_for_a_path(
270
270
  # Check whether the path exists
271
271
  if not referenced_model_path.is_file():
272
272
  continue
273
- referenced_model_uri = URI.from_path(referenced_model_path)
274
273
 
275
274
  # Extract metadata for positioning
276
275
  table_meta = TokenPositionDetails.from_meta(table.this.meta)
@@ -299,7 +298,7 @@ def get_model_definitions_for_a_path(
299
298
  )
300
299
  references.append(
301
300
  LSPExternalModelReference(
302
- uri=referenced_model_uri.value,
301
+ path=referenced_model_path,
303
302
  range=Range(
304
303
  start=to_lsp_position(start_pos_sqlmesh),
305
304
  end=to_lsp_position(end_pos_sqlmesh),
@@ -313,7 +312,7 @@ def get_model_definitions_for_a_path(
313
312
  scope=scope,
314
313
  reference_name=normalized_reference_name,
315
314
  read_file=read_file,
316
- referenced_model_uri=referenced_model_uri,
315
+ referenced_model_path=referenced_model_path,
317
316
  description=description,
318
317
  yaml_target_range=yaml_target_range,
319
318
  reference_type="external_model",
@@ -324,7 +323,7 @@ def get_model_definitions_for_a_path(
324
323
  else:
325
324
  references.append(
326
325
  LSPModelReference(
327
- uri=referenced_model_uri.value,
326
+ path=referenced_model_path,
328
327
  range=Range(
329
328
  start=to_lsp_position(start_pos_sqlmesh),
330
329
  end=to_lsp_position(end_pos_sqlmesh),
@@ -337,7 +336,7 @@ def get_model_definitions_for_a_path(
337
336
  scope=scope,
338
337
  reference_name=normalized_reference_name,
339
338
  read_file=read_file,
340
- referenced_model_uri=referenced_model_uri,
339
+ referenced_model_path=referenced_model_path,
341
340
  description=description,
342
341
  reference_type="model",
343
342
  default_catalog=lint_context.context.default_catalog,
@@ -481,10 +480,9 @@ def get_macro_reference(
481
480
  return None
482
481
 
483
482
  # Create a reference to the macro definition
484
- macro_uri = URI.from_path(path)
485
483
 
486
484
  return LSPMacroReference(
487
- uri=macro_uri.value,
485
+ path=path,
488
486
  range=to_lsp_range(macro_range),
489
487
  target_range=Range(
490
488
  start=Position(line=start_line - 1, character=0),
@@ -517,7 +515,7 @@ def get_built_in_macro_reference(macro_name: str, macro_range: Range) -> t.Optio
517
515
  end_line_number = line_number + len(source_lines) - 1
518
516
 
519
517
  return LSPMacroReference(
520
- uri=URI.from_path(Path(filename)).value,
518
+ path=Path(filename),
521
519
  range=macro_range,
522
520
  target_range=Range(
523
521
  start=Position(line=line_number - 1, character=0),
@@ -559,12 +557,12 @@ def get_model_find_all_references(
559
557
 
560
558
  assert isinstance(model_at_position, LSPModelReference) # for mypy
561
559
 
562
- target_model_uri = model_at_position.uri
560
+ target_model_path = model_at_position.path
563
561
 
564
562
  # Start with the model definition
565
563
  all_references: t.List[LSPModelReference] = [
566
564
  LSPModelReference(
567
- uri=model_at_position.uri,
565
+ path=model_at_position.path,
568
566
  range=Range(
569
567
  start=Position(line=0, character=0),
570
568
  end=Position(line=0, character=0),
@@ -575,7 +573,7 @@ def get_model_find_all_references(
575
573
 
576
574
  # Then add references from the current file
577
575
  current_file_refs = filter(
578
- lambda ref: isinstance(ref, LSPModelReference) and ref.uri == target_model_uri,
576
+ lambda ref: isinstance(ref, LSPModelReference) and ref.path == target_model_path,
579
577
  get_model_definitions_for_a_path(lint_context, document_uri),
580
578
  )
581
579
 
@@ -584,7 +582,7 @@ def get_model_find_all_references(
584
582
 
585
583
  all_references.append(
586
584
  LSPModelReference(
587
- uri=document_uri.value,
585
+ path=document_uri.to_path(),
588
586
  range=ref.range,
589
587
  markdown_description=ref.markdown_description,
590
588
  )
@@ -600,7 +598,7 @@ def get_model_find_all_references(
600
598
 
601
599
  # Get model references that point to the target model
602
600
  matching_refs = filter(
603
- lambda ref: isinstance(ref, LSPModelReference) and ref.uri == target_model_uri,
601
+ lambda ref: isinstance(ref, LSPModelReference) and ref.path == target_model_path,
604
602
  get_model_definitions_for_a_path(lint_context, file_uri),
605
603
  )
606
604
 
@@ -609,7 +607,7 @@ def get_model_find_all_references(
609
607
 
610
608
  all_references.append(
611
609
  LSPModelReference(
612
- uri=file_uri.value,
610
+ path=path,
613
611
  range=ref.range,
614
612
  markdown_description=ref.markdown_description,
615
613
  )
@@ -662,7 +660,7 @@ def get_cte_references(
662
660
  # Add the CTE definition
663
661
  matching_references = [
664
662
  LSPCteReference(
665
- uri=document_uri.value,
663
+ path=document_uri.to_path(),
666
664
  range=target_cte_definition_range,
667
665
  target_range=target_cte_definition_range,
668
666
  )
@@ -673,7 +671,7 @@ def get_cte_references(
673
671
  if ref.target_range == target_cte_definition_range:
674
672
  matching_references.append(
675
673
  LSPCteReference(
676
- uri=document_uri.value,
674
+ path=document_uri.to_path(),
677
675
  range=ref.range,
678
676
  target_range=ref.target_range,
679
677
  )
@@ -713,13 +711,13 @@ def get_macro_find_all_references(
713
711
 
714
712
  assert isinstance(macro_at_position, LSPMacroReference) # for mypy
715
713
 
716
- target_macro_uri = macro_at_position.uri
714
+ target_macro_path = macro_at_position.path
717
715
  target_macro_target_range = macro_at_position.target_range
718
716
 
719
717
  # Start with the macro definition
720
718
  all_references: t.List[LSPMacroReference] = [
721
719
  LSPMacroReference(
722
- uri=target_macro_uri,
720
+ path=target_macro_path,
723
721
  range=target_macro_target_range,
724
722
  target_range=target_macro_target_range,
725
723
  markdown_description=None,
@@ -733,7 +731,7 @@ def get_macro_find_all_references(
733
731
  # Get macro references that point to the same macro definition
734
732
  matching_refs = filter(
735
733
  lambda ref: isinstance(ref, LSPMacroReference)
736
- and ref.uri == target_macro_uri
734
+ and ref.path == target_macro_path
737
735
  and ref.target_range == target_macro_target_range,
738
736
  get_macro_definitions_for_a_path(lsp_context, file_uri),
739
737
  )
@@ -742,7 +740,7 @@ def get_macro_find_all_references(
742
740
  assert isinstance(ref, LSPMacroReference) # for mypy
743
741
  all_references.append(
744
742
  LSPMacroReference(
745
- uri=file_uri.value,
743
+ path=path,
746
744
  range=ref.range,
747
745
  target_range=ref.target_range,
748
746
  markdown_description=ref.markdown_description,
@@ -822,7 +820,7 @@ def _process_column_references(
822
820
  scope: t.Any,
823
821
  reference_name: str,
824
822
  read_file: t.List[str],
825
- referenced_model_uri: URI,
823
+ referenced_model_path: Path,
826
824
  description: t.Optional[str] = None,
827
825
  yaml_target_range: t.Optional[Range] = None,
828
826
  reference_type: t.Literal["model", "external_model", "cte"] = "model",
@@ -837,7 +835,7 @@ def _process_column_references(
837
835
  scope: The SQL scope to search for columns
838
836
  reference_name: The full reference name (may include database/catalog)
839
837
  read_file: The file content as list of lines
840
- referenced_model_uri: URI of the referenced model
838
+ referenced_model_path: Path of the referenced model
841
839
  description: Markdown description for the reference
842
840
  yaml_target_range: Target range for external models (YAML files)
843
841
  reference_type: Type of reference - "model", "external_model", or "cte"
@@ -857,7 +855,7 @@ def _process_column_references(
857
855
  table_range = _get_column_table_range(column, read_file)
858
856
  references.append(
859
857
  LSPCteReference(
860
- uri=referenced_model_uri.value,
858
+ path=referenced_model_path,
861
859
  range=table_range,
862
860
  target_range=cte_target_range,
863
861
  )
@@ -875,7 +873,7 @@ def _process_column_references(
875
873
  if reference_type == "external_model":
876
874
  references.append(
877
875
  LSPExternalModelReference(
878
- uri=referenced_model_uri.value,
876
+ path=referenced_model_path,
879
877
  range=table_range,
880
878
  markdown_description=description,
881
879
  target_range=yaml_target_range,
@@ -884,7 +882,7 @@ def _process_column_references(
884
882
  else:
885
883
  references.append(
886
884
  LSPModelReference(
887
- uri=referenced_model_uri.value,
885
+ path=referenced_model_path,
888
886
  range=table_range,
889
887
  markdown_description=description,
890
888
  )
sqlmesh/lsp/rename.py CHANGED
@@ -90,7 +90,7 @@ def _rename_cte(cte_references: t.List[LSPCteReference], new_name: str) -> Works
90
90
  changes: t.Dict[str, t.List[TextEdit]] = {}
91
91
 
92
92
  for ref in cte_references:
93
- uri = ref.uri
93
+ uri = URI.from_path(ref.path).value
94
94
  if uri not in changes:
95
95
  changes[uri] = []
96
96
 
sqlmesh/utils/hashing.py CHANGED
@@ -9,7 +9,9 @@ def crc32(data: t.Iterable[t.Optional[str]]) -> str:
9
9
  return str(zlib.crc32(_safe_concat(data)))
10
10
 
11
11
 
12
- def md5(data: t.Iterable[t.Optional[str]]) -> str:
12
+ def md5(data: t.Union[str, t.Iterable[t.Optional[str]]]) -> str:
13
+ if isinstance(data, str):
14
+ data = [data]
13
15
  return hashlib.md5(_safe_concat(data)).hexdigest()
14
16
 
15
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.204.1.dev4
3
+ Version: 0.204.1.dev6
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=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
2
- sqlmesh/_version.py,sha256=gSAeddtFclf2nCkBMyzhbPNAcqg0r8WazK7qEdi8_mY,528
2
+ sqlmesh/_version.py,sha256=z2bst6lZyy7YghpZT31C7nMoI32K7ixUo99WvUC7v3Q,528
3
3
  sqlmesh/magics.py,sha256=bEzYqXHcM0P3CjyUZ1O9arlmXAdLAhoglKbQ29fD9AE,41842
4
4
  sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -13,7 +13,7 @@ sqlmesh/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  sqlmesh/core/_typing.py,sha256=e1f7xO2aZCy38M_3VoDy-XI3shyd99-IFctgIFSgXWM,497
14
14
  sqlmesh/core/console.py,sha256=ovjM75l1A2rAi-ud3ovsIKSGwF9TsGYTK8NvokbCdL4,166111
15
15
  sqlmesh/core/constants.py,sha256=gUABXWYgH_XOSbaZAJsR5o1dmA61JDCvBDyxqqXX3LM,2630
16
- sqlmesh/core/context.py,sha256=34hhZPwqxdjLBuZ-kSlOen07CtlmD3KocQlQdXY8KeI,127454
16
+ sqlmesh/core/context.py,sha256=SkTNrp9TUNx469_mWkemhMk4leGDtmblBIWE7S64sk8,127598
17
17
  sqlmesh/core/context_diff.py,sha256=_Ur55fGLJ58Icsp44I4pVhdi7_JHiHq45mWIco9oFzk,21792
18
18
  sqlmesh/core/dialect.py,sha256=ELBtB8ft0OyalhgqQ1CUnn26xJxLDah2SP1v8kh_FB8,50903
19
19
  sqlmesh/core/environment.py,sha256=odus40R-YzdQdS_IiUq_tFouUXIhnpwmNwo8dE8Aw1k,13041
@@ -37,10 +37,10 @@ sqlmesh/core/analytics/dispatcher.py,sha256=SQw5tHIETb7ei_oCj7ktHEJyeJNbKyIYiOPx
37
37
  sqlmesh/core/audit/__init__.py,sha256=3jogKe-G4X0rOxwH5QVuRRioyesQffSWxKU4PVwMPvA,216
38
38
  sqlmesh/core/audit/builtin.py,sha256=adA-cFCphB66jVY4n66cbwbRTFF1FTEIMrLhRDpbBo0,17783
39
39
  sqlmesh/core/audit/definition.py,sha256=QXXObhR_jHgjWLu0qXxPuIXm0GlFQq33rhp11m_xAUU,18306
40
- sqlmesh/core/config/__init__.py,sha256=b4gFb04tpeZpowqJD-7h3U3TLgxrpQhZahVEAo6VW2Y,2009
40
+ sqlmesh/core/config/__init__.py,sha256=5zxTXjUMuxBj4XlX6bmpIWTp4GsZY5rIdKSCTYbxRBM,2070
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
- sqlmesh/core/config/common.py,sha256=rsb2uVFqPEX3DMsWG_hApwztCuRJP-FAmaQ_5L3-S8g,4006
43
+ sqlmesh/core/config/common.py,sha256=HZxek5DrzdFQl22BypSqB_8amsIT8tqUFSgh66Ibxwk,5158
44
44
  sqlmesh/core/config/connection.py,sha256=NcS1qB0MKIBCfw6vUNLhalVKZTo2igS7VTrcV_T-VgA,88607
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
@@ -52,7 +52,7 @@ sqlmesh/core/config/migration.py,sha256=3lZIlmIcQH3_hIEm3Y3jFtvpw0YXzRzAnk4Odikl
52
52
  sqlmesh/core/config/model.py,sha256=xDKIHD8WIzsPu7DfpybPM3bLobppttCZjvD3TTVnwps,4182
53
53
  sqlmesh/core/config/naming.py,sha256=KVGaxUgswoQajXR_cHFJvgkmEFcU1V182GkOH1SJxuE,326
54
54
  sqlmesh/core/config/plan.py,sha256=wJEDfocMcKSMN0-5gVojjIcmJZ0376LJU3tkGMTm-Zc,1558
55
- sqlmesh/core/config/root.py,sha256=-ev6H4Qi0rlwiO8NyvgGXsunkvpVpaRZD6ZCuTDF4V4,16223
55
+ sqlmesh/core/config/root.py,sha256=XEp_BSTMODsIts86W_lA87FPJdlz1CH1DSvU4VdqszE,16468
56
56
  sqlmesh/core/config/run.py,sha256=rIK0QnN_vArrwps2TXGVEbvao2AnGZgzXo7EliJa42E,852
57
57
  sqlmesh/core/config/scheduler.py,sha256=LVEHIln7dqv8ygo4uniji4j9-gfuJlk-WpQU9FAqILs,7031
58
58
  sqlmesh/core/config/ui.py,sha256=jsO-S6_d9NkLZGG5pT4mgKgxMF34KzkDociZAMvCX3U,278
@@ -102,7 +102,7 @@ sqlmesh/core/plan/stages.py,sha256=JN7rwo6ibY5Ctqof3Us7Eu2x85n5GXH0rCA47BBvP1o,2
102
102
  sqlmesh/core/snapshot/__init__.py,sha256=Z5HTetNCZGoKF1WAKXk4LWL9dc8EC8lwS2O4TtoBmt4,1317
103
103
  sqlmesh/core/snapshot/cache.py,sha256=bgqCR2hyf6r2A_8QP1EnXFK25gDX37-Zg0YeMuETWxg,3934
104
104
  sqlmesh/core/snapshot/categorizer.py,sha256=qGG5870mu1jR2whKisSBH_GFbsyh96RnzJDgkN7DV9g,2482
105
- sqlmesh/core/snapshot/definition.py,sha256=DwYTNcDfPQUQ1osF_63SdicSj7oqVjtmPPEzqwsxDLU,85748
105
+ sqlmesh/core/snapshot/definition.py,sha256=JRNNrN9KYAQGM-BfL7osCRjGPRWh3PIX_CD-cnXnT4s,88135
106
106
  sqlmesh/core/snapshot/evaluator.py,sha256=9l73YNKTEu9N91JTSxnxLqQo-lAaX6ihPxVNi4wUfFQ,91846
107
107
  sqlmesh/core/state_sync/__init__.py,sha256=B60xj-_Xk-4jas3UphLvwkuf04G-9AyGckcblXE0aRg,869
108
108
  sqlmesh/core/state_sync/base.py,sha256=AdqWmbhnvRFqVcFK6L01uCvpBVAYGuMrm4P0D3u_NaU,18334
@@ -171,9 +171,9 @@ sqlmesh/lsp/description.py,sha256=PjguwyVw5YeYSgT0JMhkf5U1Jry-sDPLvQ2caIR9JPQ,85
171
171
  sqlmesh/lsp/errors.py,sha256=3NMim_5J00Eypz7t8b7XbkBfy8gIsRkeq-VcjD4COtc,1489
172
172
  sqlmesh/lsp/helpers.py,sha256=EFc1u3-b7kSv5-tNwmKUDxId72RCLDBnN2lLTgRSzzQ,1020
173
173
  sqlmesh/lsp/hints.py,sha256=j-blccBUil94yRoDjWfkSM0HqMmsKD6hP2TaWdWWVk4,3734
174
- sqlmesh/lsp/main.py,sha256=ZOcANYSo9_1tanuRyvpNrE43DpHTyCsYmOEWWJFFa0o,39964
175
- sqlmesh/lsp/reference.py,sha256=YFg0DwwCcr7A99ZJV69V1H3oYmEw4uRFrhhAYR3SJYw,33160
176
- sqlmesh/lsp/rename.py,sha256=399v1vyVRHHxvbCHVcuS4Pl8K2N-Z60JdZ6e1znOI4s,4397
174
+ sqlmesh/lsp/main.py,sha256=lTFXCaqSxJOS2ftGuvx65d4whgJV0iz25vtkB3Qt3kI,40010
175
+ sqlmesh/lsp/reference.py,sha256=PD9lfihjQIN9pmllzEWL2qXtZtvktAL8_ybmPJ-8W-I,33038
176
+ sqlmesh/lsp/rename.py,sha256=OwZsgEqK5sQkHXEx2SwINxquGF92xkHZ9nQLl7SqUiY,4419
177
177
  sqlmesh/lsp/uri.py,sha256=mvSLbZGmMTHPpliThOtVWiFcHnfJzp1w39q9l-xD2SI,802
178
178
  sqlmesh/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
179
  sqlmesh/migrations/v0001_init.py,sha256=h8FwMYJj9_O8yGpk12guaSaGwX5A3we2GiKeHrXi15o,2048
@@ -275,7 +275,7 @@ sqlmesh/utils/dag.py,sha256=L_jwKf81wCySmt1TFs4vEKsrIHSOPTBhptlmv1bsSSg,7025
275
275
  sqlmesh/utils/date.py,sha256=uS0Kii4hFJeTXqXtM39sDCzvFhTAoPk_NPg51T1YYeo,16218
276
276
  sqlmesh/utils/errors.py,sha256=8FE33Eo3KN3Y4s5EZM5t92jZi9BAVGzkr3QCGlrLeDk,5679
277
277
  sqlmesh/utils/git.py,sha256=v1MD4Zwn52UBn_tTfoKn8SAPJVGC6SEFrJ4WEJFbgF0,1868
278
- sqlmesh/utils/hashing.py,sha256=4Bi0NvRctBHzg58btNxXwSNgcvj8doIVVvOjJ40mHBg,512
278
+ sqlmesh/utils/hashing.py,sha256=nZRKvLNQ83tLG4IoXshVJZf-MbDrXC1HOeNw8Ji-tMM,578
279
279
  sqlmesh/utils/jinja.py,sha256=zulSPIICdFOjN__xkAiMpxbCS7S0--xAFK9d8VG0KvU,27844
280
280
  sqlmesh/utils/metaprogramming.py,sha256=yDWS3_tkm6Yd5TNHgii2x_VdZ2pVM0vL6oFuwFMMs0A,23554
281
281
  sqlmesh/utils/migration.py,sha256=R7Ck6FX-LfcujGy7sgS0kDWlK-xAEBODr3gqIQ8gC08,835
@@ -285,7 +285,7 @@ sqlmesh/utils/pydantic.py,sha256=o_NsXbIpDqNpUA1Uc5xF0ZzoXQYYB0DfHwdRxBwXPNk,120
285
285
  sqlmesh/utils/rich.py,sha256=cwQ5nJ6sgz64xHtoh6_ec7ReV5YpsOGhMtUJnwoRfEI,3549
286
286
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
287
287
  sqlmesh/utils/yaml.py,sha256=hvo5lmybYLcIx4p6CQwufS8X4MbwS60lEBnCmYJCXmU,2336
288
- sqlmesh-0.204.1.dev4.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
288
+ sqlmesh-0.204.1.dev6.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
289
289
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
290
290
  web/client/dist/index.html,sha256=SXykdSRNgrT1k6I2dPZPEfpxPjIsi8-yVFijt-naSA4,5472
291
291
  web/client/dist/assets/Audits-Jm353fhk.js,sha256=ry6b5IKT3hLAfD5C3T2BqxulfauEV0n0YZ2vsP4eQ_U,1041
@@ -403,8 +403,8 @@ web/server/api/endpoints/models.py,sha256=kwj0s7uve3iZSMfmjkoPVMFMeY1sD0peTeyrWf
403
403
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
404
404
  web/server/api/endpoints/plan.py,sha256=bbbY50W_2MsZSTxOHWMKz0tbIm75nsRSlPy8GI2fg9Q,9306
405
405
  web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
406
- sqlmesh-0.204.1.dev4.dist-info/METADATA,sha256=O_WE277wyBA6qWGMWNhTkdmCV8yJrphTILnACvNFqPU,26678
407
- sqlmesh-0.204.1.dev4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
408
- sqlmesh-0.204.1.dev4.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
409
- sqlmesh-0.204.1.dev4.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
410
- sqlmesh-0.204.1.dev4.dist-info/RECORD,,
406
+ sqlmesh-0.204.1.dev6.dist-info/METADATA,sha256=OwTowzEaVG2PoyaqSaW0u7YDPOP8Pka8vfovlN6Qzh0,26678
407
+ sqlmesh-0.204.1.dev6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
408
+ sqlmesh-0.204.1.dev6.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
409
+ sqlmesh-0.204.1.dev6.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
410
+ sqlmesh-0.204.1.dev6.dist-info/RECORD,,