sqlmesh 0.181.2.dev2__py3-none-any.whl → 0.181.2.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.181.2.dev2'
21
- __version_tuple__ = version_tuple = (0, 181, 2, 'dev2')
20
+ __version__ = version = '0.181.2.dev4'
21
+ __version_tuple__ = version_tuple = (0, 181, 2, 'dev4')
sqlmesh/core/console.py CHANGED
@@ -2181,6 +2181,12 @@ class TerminalConsole(Console):
2181
2181
  def show_row_diff(
2182
2182
  self, row_diff: RowDiff, show_sample: bool = True, skip_grain_check: bool = False
2183
2183
  ) -> None:
2184
+ if row_diff.empty:
2185
+ self.console.print(
2186
+ "\n[b][red]Neither the source nor the target table contained any records[/red][/b]"
2187
+ )
2188
+ return
2189
+
2184
2190
  source_name = row_diff.source
2185
2191
  if row_diff.source_alias:
2186
2192
  source_name = row_diff.source_alias.upper()
@@ -8,11 +8,20 @@ from typing import Type
8
8
 
9
9
  import typing as t
10
10
 
11
+ from sqlmesh.utils.pydantic import PydanticModel
12
+
11
13
 
12
14
  if t.TYPE_CHECKING:
13
15
  from sqlmesh.core.context import GenericContext
14
16
 
15
17
 
18
+ class RuleLocation(PydanticModel):
19
+ """The location of a rule in a file."""
20
+
21
+ file_path: str
22
+ start_line: t.Optional[int] = None
23
+
24
+
16
25
  class _Rule(abc.ABCMeta):
17
26
  def __new__(cls: Type[_Rule], clsname: str, bases: t.Tuple, attrs: t.Dict) -> _Rule:
18
27
  attrs["name"] = clsname.lower()
@@ -40,6 +49,31 @@ class Rule(abc.ABC, metaclass=_Rule):
40
49
  """Create a RuleViolation instance for this rule"""
41
50
  return RuleViolation(rule=self, violation_msg=violation_msg or self.summary)
42
51
 
52
+ def get_definition_location(self) -> RuleLocation:
53
+ """Return the file path and position information for this rule.
54
+
55
+ This method returns information about where this rule is defined,
56
+ which can be used in diagnostics to link to the rule's documentation.
57
+
58
+ Returns:
59
+ A dictionary containing file path and position information.
60
+ """
61
+ import inspect
62
+
63
+ # Get the file where the rule class is defined
64
+ file_path = inspect.getfile(self.__class__)
65
+
66
+ try:
67
+ # Get the source code and line number
68
+ source_lines, start_line = inspect.getsourcelines(self.__class__)
69
+ return RuleLocation(
70
+ file_path=file_path,
71
+ start_line=start_line,
72
+ )
73
+ except (IOError, TypeError):
74
+ # Fall back to just returning the file path if we can't get source lines
75
+ return RuleLocation(file_path=file_path)
76
+
43
77
  def __repr__(self) -> str:
44
78
  return self.name
45
79
 
@@ -83,6 +83,15 @@ class RowDiff(PydanticModel, frozen=True):
83
83
  """Count of the target."""
84
84
  return int(self.stats["t_count"])
85
85
 
86
+ @property
87
+ def empty(self) -> bool:
88
+ return (
89
+ self.source_count == 0
90
+ and self.target_count == 0
91
+ and self.s_only_count == 0
92
+ and self.t_only_count == 0
93
+ )
94
+
86
95
  @property
87
96
  def count_pct_change(self) -> float:
88
97
  """The percentage change of the counts."""
@@ -446,7 +455,7 @@ class TableDiff:
446
455
 
447
456
  summary_query = exp.select(*summary_sums).from_(table)
448
457
 
449
- stats_df = self.adapter.fetchdf(summary_query, quote_identifiers=True)
458
+ stats_df = self.adapter.fetchdf(summary_query, quote_identifiers=True).fillna(0)
450
459
  stats_df["s_only_count"] = stats_df["s_count"] - stats_df["join_count"]
451
460
  stats_df["t_only_count"] = stats_df["t_count"] - stats_df["join_count"]
452
461
  stats = stats_df.iloc[0].to_dict()
sqlmesh/lsp/main.py CHANGED
@@ -293,6 +293,12 @@ class SQLMeshLanguageServer:
293
293
  return None
294
294
  with open(diagnostic.model._path, "r", encoding="utf-8") as file:
295
295
  lines = file.readlines()
296
+
297
+ # Get rule definition location for diagnostics link
298
+ rule_location = diagnostic.rule.get_definition_location()
299
+ rule_uri = f"file://{rule_location.file_path}#L{rule_location.start_line}"
300
+
301
+ # Use URI format to create a link for "related information"
296
302
  return types.Diagnostic(
297
303
  range=types.Range(
298
304
  start=types.Position(line=0, character=0),
@@ -302,6 +308,9 @@ class SQLMeshLanguageServer:
302
308
  severity=types.DiagnosticSeverity.Error
303
309
  if diagnostic.violation_type == "error"
304
310
  else types.DiagnosticSeverity.Warning,
311
+ source="sqlmesh",
312
+ code=diagnostic.rule.name,
313
+ code_description=types.CodeDescription(href=rule_uri),
305
314
  )
306
315
 
307
316
  @staticmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.181.2.dev2
3
+ Version: 0.181.2.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=UTbksF6FJCdg25HnFVlHkCpBV5LKcoc82FJhyR3Jh4E,528
2
+ sqlmesh/_version.py,sha256=D1YsWYwvIVwHOZALEdwu3KaQkZgOdRujhZQQlapnWUU,528
3
3
  sqlmesh/magics.py,sha256=9oY1Uz8uwsuTtPRg9HTYDxnGiJ7-OVRCpmCgAhbKHUU,39431
4
4
  sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -11,7 +11,7 @@ sqlmesh/cli/main.py,sha256=z1Af0bwqtnYHzkY0_9REpaJe-onxvXN4rLw6upyxKec,31979
11
11
  sqlmesh/cli/options.py,sha256=aC_L5WnMScKzMU55BD1Y-8R-QzqCkPSYrlCI-payHRA,1333
12
12
  sqlmesh/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  sqlmesh/core/_typing.py,sha256=e1f7xO2aZCy38M_3VoDy-XI3shyd99-IFctgIFSgXWM,497
14
- sqlmesh/core/console.py,sha256=qPMcYwr4ktv8BJe7-2vYI3N5534mdviihK4p9YipuMQ,149415
14
+ sqlmesh/core/console.py,sha256=-FGOalIrfCN5ZyDIYW8Emx3GIF9qeaNfNW00lUogoFg,149608
15
15
  sqlmesh/core/constants.py,sha256=oqt6zjepUhQoWlgapKn_HpG7Pu9mrFwepdX5caNfJUI,2499
16
16
  sqlmesh/core/context.py,sha256=kLKXwOLc_5Orv-SxvI0zbpL9ZJ0XkB9HZgd9R6uh-9Y,114691
17
17
  sqlmesh/core/context_diff.py,sha256=s9toP17d4tJfOpFH91LcjGK2CM64PVuB0MPkeFgF4hQ,20415
@@ -29,7 +29,7 @@ sqlmesh/core/schema_diff.py,sha256=mE28W51JUQz6q8inSOw2Cds84VPIqPxI6C2ed6xLmrg,2
29
29
  sqlmesh/core/schema_loader.py,sha256=lvrI9k7hr1P4X4E6t3U-KrcuvdQuw0UdNlN90P2s52w,3563
30
30
  sqlmesh/core/selector.py,sha256=9riBQ6gPySg546x0JaXXITw2eZgGe9iVKcynAUJ1mmw,12137
31
31
  sqlmesh/core/signal.py,sha256=yVLXewYP6eH0vt-EwaIaI2WwHz6hWsVr-Kb2m4kP1FU,1353
32
- sqlmesh/core/table_diff.py,sha256=equXUvsH5U5l_fS3xtTDuyEzXZLzQyW_WfSzQI3dCb0,23237
32
+ sqlmesh/core/table_diff.py,sha256=lfEzA-3xYIUkrnz7cAgq1vd6h6BGWnEuVSXwWNBJL9U,23470
33
33
  sqlmesh/core/user.py,sha256=EJ6R4R1iK67n80vBoCCsidF56IR7xEYqiCEO-nrVMso,1660
34
34
  sqlmesh/core/analytics/__init__.py,sha256=ou3ZXAJfQOXEifj-PzaXwMDSvJzsVaqaMkUopiI00kM,3247
35
35
  sqlmesh/core/analytics/collector.py,sha256=sggJvER16Jrg5triTC27E2KwaQvfkVDv4D6R1lVPH5I,13058
@@ -77,7 +77,7 @@ sqlmesh/core/engine_adapter/spark.py,sha256=VOXStkBBZIzebPo_ivdQFvZtRMiWJHHo7h11
77
77
  sqlmesh/core/engine_adapter/trino.py,sha256=pZ2E1owyC6DPmkU3RkibR3CIE1gE-8fNd016YHh52II,14915
78
78
  sqlmesh/core/linter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
79
  sqlmesh/core/linter/definition.py,sha256=UL05OjFBfoLSYGWXNf4zjZYzIKr-OyFIMIcIh7RhR8s,5237
80
- sqlmesh/core/linter/rule.py,sha256=Y9i0tpu53INrYSy6qT0cEvVziPOGNbWZwPfY9yi_lLM,1435
80
+ sqlmesh/core/linter/rule.py,sha256=p8rbMbf2Z18ZJ6ZcZyoCk-3Lvo7d_Gvc35tiwWXvuQs,2579
81
81
  sqlmesh/core/linter/rules/__init__.py,sha256=gevzfb67vFqckTCoVAe_TBGf6hQ-YtE1_YuGuXyh1L0,77
82
82
  sqlmesh/core/linter/rules/builtin.py,sha256=RXns3e042q8aM-3wDUNDc7dcX5hDiOO7qel1YnjeqUk,1950
83
83
  sqlmesh/core/metric/__init__.py,sha256=H1HmoD5IwN4YWe9iJXyueLYNmTQFZwok5nSWNJcZIBQ,237
@@ -158,7 +158,7 @@ sqlmesh/integrations/github/cicd/controller.py,sha256=AiEMsRW4WSVxXP_7oQSIdzBzmY
158
158
  sqlmesh/lsp/completions.py,sha256=ScW0H9couhfW6QckEX2djVYTClRPXpT2Hdcg1qLfUUY,3479
159
159
  sqlmesh/lsp/context.py,sha256=vUpbWYjKYuwDvU3zkzhAgw9An-TeVYe_5KTk-ec_UwM,1569
160
160
  sqlmesh/lsp/custom.py,sha256=GvNAiW7imPI8xmIx3qLWN5FljGPHFJKh0N5b6aZnwRo,489
161
- sqlmesh/lsp/main.py,sha256=OftpChYMN1_sNeaLM5wxK5umiHCiOwPNnFFpaG6sAu8,14774
161
+ sqlmesh/lsp/main.py,sha256=cB3yUQq6E8mUxa-ZSwQrjKuiw-Cto9zDnHjLEg0mgJs,15189
162
162
  sqlmesh/lsp/reference.py,sha256=2rANWlO4Z4Pt9KuUhZSWoaTdPfmeNVDgi7iiXFTb7zY,8076
163
163
  sqlmesh/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
164
  sqlmesh/migrations/v0001_init.py,sha256=h8FwMYJj9_O8yGpk12guaSaGwX5A3we2GiKeHrXi15o,2048
@@ -265,7 +265,7 @@ sqlmesh/utils/pandas.py,sha256=j_tYhuPcWpzuPceZZ6IhdTVbmxYyGJW7l4FHr4bQqjM,1824
265
265
  sqlmesh/utils/pydantic.py,sha256=ioaAzYF42PutEJRyAS11-AHguiCG3yWI6VRcTVa2G-g,10470
266
266
  sqlmesh/utils/rich.py,sha256=xNZyPCqEc4TAlJlsEthg-5eYUWpaizz0QjBzO7a1Yv4,1509
267
267
  sqlmesh/utils/yaml.py,sha256=np-WVcwmwsKghCgAj1OBBMsK1SXSRn4wR-H37cGiFr8,2282
268
- sqlmesh-0.181.2.dev2.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
268
+ sqlmesh-0.181.2.dev4.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
269
269
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
270
270
  web/client/dist/index.html,sha256=cQRIlDgkl6OgeWuHI9hM8bJhKUE9-Ji2NpQa2hlgNM8,5472
271
271
  web/client/dist/assets/Audits-4U9LnWyN.js,sha256=reXu-sKJ76kiaAZIGkCPvgO68Km9tj1PN_9mx6X6WAY,997
@@ -382,8 +382,8 @@ web/server/api/endpoints/models.py,sha256=SzS5bshzdXyM6hb948sZ_3k-xhpGCHkxkb7pHz
382
382
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
383
383
  web/server/api/endpoints/plan.py,sha256=OYuQ_4dgbhG9ibTcX1a8mvYgH3ANxw9Fhbb4wg6QWqc,9222
384
384
  web/server/api/endpoints/table_diff.py,sha256=Wd5YxeKbZB7AkrDvqFgvV9ZQlnKYOF1n5W_w2EHE_Zw,2085
385
- sqlmesh-0.181.2.dev2.dist-info/METADATA,sha256=Bn9XxP3OdiKwnsN8Vz7gSJc2oSTWiyYU9hVKWm0c5Cs,25307
386
- sqlmesh-0.181.2.dev2.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
387
- sqlmesh-0.181.2.dev2.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
388
- sqlmesh-0.181.2.dev2.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
389
- sqlmesh-0.181.2.dev2.dist-info/RECORD,,
385
+ sqlmesh-0.181.2.dev4.dist-info/METADATA,sha256=ZXdxc0x6HYIDfi7ta-ok_xIj0HYw0t6aSWKsj7k4jV4,25307
386
+ sqlmesh-0.181.2.dev4.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
387
+ sqlmesh-0.181.2.dev4.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
388
+ sqlmesh-0.181.2.dev4.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
389
+ sqlmesh-0.181.2.dev4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.4.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5