sqlmesh 0.205.1.dev20__py3-none-any.whl → 0.205.1.dev21__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.205.1.dev20'
21
- __version_tuple__ = version_tuple = (0, 205, 1, 'dev20')
20
+ __version__ = version = '0.205.1.dev21'
21
+ __version_tuple__ = version_tuple = (0, 205, 1, 'dev21')
@@ -7,13 +7,14 @@ import typing as t
7
7
  from sqlglot.expressions import Star
8
8
  from sqlglot.helper import subclasses
9
9
 
10
+ from sqlmesh.core.constants import EXTERNAL_MODELS_YAML
10
11
  from sqlmesh.core.dialect import normalize_model_name
11
12
  from sqlmesh.core.linter.helpers import (
12
13
  TokenPositionDetails,
13
14
  get_range_of_model_block,
14
15
  read_range_from_string,
15
16
  )
16
- from sqlmesh.core.linter.rule import Rule, RuleViolation, Range, Fix, TextEdit
17
+ from sqlmesh.core.linter.rule import Rule, RuleViolation, Range, Fix, TextEdit, Position
17
18
  from sqlmesh.core.linter.definition import RuleSet
18
19
  from sqlmesh.core.model import Model, SqlModel, ExternalModel
19
20
  from sqlmesh.utils.lineage import extract_references_from_query, ExternalModelReference
@@ -185,12 +186,14 @@ class NoMissingExternalModels(Rule):
185
186
  violations = []
186
187
  for ref_name, ref in external_references.items():
187
188
  if ref_name in not_registered_external_models:
189
+ fix = self.create_fix(ref_name)
188
190
  violations.append(
189
191
  RuleViolation(
190
192
  rule=self,
191
193
  violation_msg=f"Model '{model.fqn}' depends on unregistered external model '{ref_name}'. "
192
194
  "Please register it in the external models file. This can be done by running 'sqlmesh create_external_models'.",
193
195
  violation_range=ref.range,
196
+ fixes=[fix] if fix else [],
194
197
  )
195
198
  )
196
199
 
@@ -212,5 +215,46 @@ class NoMissingExternalModels(Rule):
212
215
  "Please register them in the external models file. This can be done by running 'sqlmesh create_external_models'.",
213
216
  )
214
217
 
218
+ def create_fix(self, model_name: str) -> t.Optional[Fix]:
219
+ """
220
+ Add an external model to the external models file.
221
+ - If no external models file exists, it will create one with the model.
222
+ - If the model already exists, it will not add it again.
223
+ """
224
+ root = self.context.path
225
+ if not root:
226
+ return None
227
+
228
+ external_models_path = root / EXTERNAL_MODELS_YAML
229
+ if not external_models_path.exists():
230
+ return None
231
+
232
+ # Figure out the position to insert the new external model at the end of the file, whether
233
+ # needs new line or not.
234
+ with open(external_models_path, "r", encoding="utf-8") as file:
235
+ lines = file.read()
236
+
237
+ # If a file ends in newline, we can add the new model directly.
238
+ split_lines = lines.splitlines()
239
+ if lines.endswith("\n"):
240
+ new_text = f"- name: '{model_name}'\n"
241
+ position = Position(line=len(split_lines), character=0)
242
+ else:
243
+ new_text = f"\n- name: '{model_name}'\n"
244
+ position = Position(
245
+ line=len(split_lines) - 1, character=len(split_lines[-1]) if split_lines else 0
246
+ )
247
+
248
+ return Fix(
249
+ title="Add external model",
250
+ edits=[
251
+ TextEdit(
252
+ path=external_models_path,
253
+ range=Range(start=position, end=position),
254
+ new_text=new_text,
255
+ )
256
+ ],
257
+ )
258
+
215
259
 
216
260
  BUILTIN_RULES = RuleSet(subclasses(__name__, Rule, (Rule,)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.205.1.dev20
3
+ Version: 0.205.1.dev21
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=GkqA44FmLbBN3arn4mtDTndnuKRKMu7IjVw8OfFWe8k,530
2
+ sqlmesh/_version.py,sha256=uvArl7UUkT0NZv1Ks5i0VNvGFS9GXml10bM7Ox2RGTs,530
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
@@ -80,7 +80,7 @@ sqlmesh/core/linter/definition.py,sha256=JDJTkhByUw4Tr3nF-BOHKFAx_eASQqEqzX6AUVQ
80
80
  sqlmesh/core/linter/helpers.py,sha256=HNNSiuKB2o4Z2AGbwgrGr9hE0lQnIR7VHQfj8D8M_Jw,5202
81
81
  sqlmesh/core/linter/rule.py,sha256=MgFwfvlGEvh4nijsxc7Bbk_S9ctJ_m-nKCom9LIN4W4,3734
82
82
  sqlmesh/core/linter/rules/__init__.py,sha256=gevzfb67vFqckTCoVAe_TBGf6hQ-YtE1_YuGuXyh1L0,77
83
- sqlmesh/core/linter/rules/builtin.py,sha256=RmKZrp3EWLSmP-X_gT2gl_SVmIImPoZjwJWki1sYBIo,8180
83
+ sqlmesh/core/linter/rules/builtin.py,sha256=2H4yV4eVUCY25uFgO2M62czpZt5dXdK5mW6XGGOc12Q,9857
84
84
  sqlmesh/core/metric/__init__.py,sha256=H1HmoD5IwN4YWe9iJXyueLYNmTQFZwok5nSWNJcZIBQ,237
85
85
  sqlmesh/core/metric/definition.py,sha256=Yd5aVgsZCDPJ43aGP7WqtzZOuuSUtB8uJGVA6Jw9x9M,7201
86
86
  sqlmesh/core/metric/rewriter.py,sha256=GiSTHfn2kinqCfNPYgZPRk93JFLzVaaejHtHDQ0yXZI,7326
@@ -287,7 +287,7 @@ sqlmesh/utils/pydantic.py,sha256=o_NsXbIpDqNpUA1Uc5xF0ZzoXQYYB0DfHwdRxBwXPNk,120
287
287
  sqlmesh/utils/rich.py,sha256=cwQ5nJ6sgz64xHtoh6_ec7ReV5YpsOGhMtUJnwoRfEI,3549
288
288
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
289
289
  sqlmesh/utils/yaml.py,sha256=hvo5lmybYLcIx4p6CQwufS8X4MbwS60lEBnCmYJCXmU,2336
290
- sqlmesh-0.205.1.dev20.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
290
+ sqlmesh-0.205.1.dev21.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
291
291
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
292
292
  web/client/dist/index.html,sha256=SXykdSRNgrT1k6I2dPZPEfpxPjIsi8-yVFijt-naSA4,5472
293
293
  web/client/dist/assets/Audits-Jm353fhk.js,sha256=ry6b5IKT3hLAfD5C3T2BqxulfauEV0n0YZ2vsP4eQ_U,1041
@@ -405,8 +405,8 @@ web/server/api/endpoints/models.py,sha256=kwj0s7uve3iZSMfmjkoPVMFMeY1sD0peTeyrWf
405
405
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
406
406
  web/server/api/endpoints/plan.py,sha256=bbbY50W_2MsZSTxOHWMKz0tbIm75nsRSlPy8GI2fg9Q,9306
407
407
  web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
408
- sqlmesh-0.205.1.dev20.dist-info/METADATA,sha256=LvQ9ZUIDmgH6RTQH9OI6m4stcnRpdLCCiRWU28i70KM,26686
409
- sqlmesh-0.205.1.dev20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
410
- sqlmesh-0.205.1.dev20.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
411
- sqlmesh-0.205.1.dev20.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
412
- sqlmesh-0.205.1.dev20.dist-info/RECORD,,
408
+ sqlmesh-0.205.1.dev21.dist-info/METADATA,sha256=RRkaqgMA5WuwjWQjkA2zY_0vkVgX7NXRMk03OHjWxps,26686
409
+ sqlmesh-0.205.1.dev21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
410
+ sqlmesh-0.205.1.dev21.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
411
+ sqlmesh-0.205.1.dev21.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
412
+ sqlmesh-0.205.1.dev21.dist-info/RECORD,,