sqlmesh 0.180.1.dev7__py3-none-any.whl → 0.180.1.dev9__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/lsp/completions.py +32 -14
- sqlmesh/lsp/context.py +38 -5
- sqlmesh/lsp/main.py +10 -4
- sqlmesh/lsp/reference.py +38 -14
- {sqlmesh-0.180.1.dev7.dist-info → sqlmesh-0.180.1.dev9.dist-info}/METADATA +2 -2
- {sqlmesh-0.180.1.dev7.dist-info → sqlmesh-0.180.1.dev9.dist-info}/RECORD +11 -11
- {sqlmesh-0.180.1.dev7.dist-info → sqlmesh-0.180.1.dev9.dist-info}/WHEEL +0 -0
- {sqlmesh-0.180.1.dev7.dist-info → sqlmesh-0.180.1.dev9.dist-info}/entry_points.txt +0 -0
- {sqlmesh-0.180.1.dev7.dist-info → sqlmesh-0.180.1.dev9.dist-info}/licenses/LICENSE +0 -0
- {sqlmesh-0.180.1.dev7.dist-info → sqlmesh-0.180.1.dev9.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.180.1.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 180, 1, '
|
|
20
|
+
__version__ = version = '0.180.1.dev9'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 180, 1, 'dev9')
|
sqlmesh/lsp/completions.py
CHANGED
|
@@ -2,7 +2,7 @@ from functools import lru_cache
|
|
|
2
2
|
from sqlglot import Dialect, Tokenizer
|
|
3
3
|
from sqlmesh.lsp.custom import AllModelsResponse
|
|
4
4
|
import typing as t
|
|
5
|
-
from sqlmesh.lsp.context import LSPContext
|
|
5
|
+
from sqlmesh.lsp.context import AuditTarget, LSPContext, ModelTarget
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def get_sql_completions(context: t.Optional[LSPContext], file_uri: str) -> AllModelsResponse:
|
|
@@ -24,11 +24,20 @@ def get_models(context: t.Optional[LSPContext], file_uri: t.Optional[str]) -> t.
|
|
|
24
24
|
"""
|
|
25
25
|
if context is None:
|
|
26
26
|
return set()
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
|
|
28
|
+
all_models = set()
|
|
29
|
+
# Extract model names from ModelInfo objects
|
|
30
|
+
for file_info in context.map.values():
|
|
31
|
+
if isinstance(file_info, ModelTarget):
|
|
32
|
+
all_models.update(file_info.names)
|
|
33
|
+
|
|
34
|
+
# Remove models from the current file
|
|
35
|
+
if file_uri is not None and file_uri in context.map:
|
|
36
|
+
file_info = context.map[file_uri]
|
|
37
|
+
if isinstance(file_info, ModelTarget):
|
|
38
|
+
for model in file_info.names:
|
|
39
|
+
all_models.discard(model)
|
|
40
|
+
|
|
32
41
|
return all_models
|
|
33
42
|
|
|
34
43
|
|
|
@@ -43,16 +52,25 @@ def get_keywords(context: t.Optional[LSPContext], file_uri: t.Optional[str]) ->
|
|
|
43
52
|
If both a context and a file_uri are provided, returns the keywords
|
|
44
53
|
for the dialect of the model that the file belongs to.
|
|
45
54
|
"""
|
|
46
|
-
if file_uri is not None and context is not None:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
if file_uri is not None and context is not None and file_uri in context.map:
|
|
56
|
+
file_info = context.map[file_uri]
|
|
57
|
+
|
|
58
|
+
# Handle ModelInfo objects
|
|
59
|
+
if isinstance(file_info, ModelTarget) and file_info.names:
|
|
60
|
+
model_name = file_info.names[0]
|
|
61
|
+
model_from_context = context.context.get_model(model_name)
|
|
62
|
+
if model_from_context is not None and model_from_context.dialect:
|
|
63
|
+
return get_keywords_from_tokenizer(model_from_context.dialect)
|
|
64
|
+
|
|
65
|
+
# Handle AuditInfo objects
|
|
66
|
+
elif isinstance(file_info, AuditTarget) and file_info.name:
|
|
67
|
+
audit = context.context.standalone_audits.get(file_info.name)
|
|
68
|
+
if audit is not None and audit.dialect:
|
|
69
|
+
return get_keywords_from_tokenizer(audit.dialect)
|
|
70
|
+
|
|
54
71
|
if context is not None:
|
|
55
72
|
return get_keywords_from_tokenizer(context.context.default_dialect)
|
|
73
|
+
|
|
56
74
|
return get_keywords_from_tokenizer(None)
|
|
57
75
|
|
|
58
76
|
|
sqlmesh/lsp/context.py
CHANGED
|
@@ -1,20 +1,53 @@
|
|
|
1
|
-
from
|
|
1
|
+
from dataclasses import dataclass
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from sqlmesh.core.context import Context
|
|
4
4
|
import typing as t
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
@dataclass
|
|
8
|
+
class ModelTarget:
|
|
9
|
+
"""Information about models in a file."""
|
|
10
|
+
|
|
11
|
+
names: t.List[str]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class AuditTarget:
|
|
16
|
+
"""Information about standalone audits in a file."""
|
|
17
|
+
|
|
18
|
+
name: str
|
|
19
|
+
|
|
20
|
+
|
|
7
21
|
class LSPContext:
|
|
8
22
|
"""
|
|
9
|
-
A context that is used for linting. It contains the context and a reverse map of file uri to
|
|
23
|
+
A context that is used for linting. It contains the context and a reverse map of file uri to
|
|
24
|
+
model names and standalone audit names.
|
|
10
25
|
"""
|
|
11
26
|
|
|
12
27
|
def __init__(self, context: Context) -> None:
|
|
13
28
|
self.context = context
|
|
14
|
-
|
|
29
|
+
|
|
30
|
+
# Add models to the map
|
|
31
|
+
model_map: t.Dict[str, ModelTarget] = {}
|
|
15
32
|
for model in context.models.values():
|
|
16
33
|
if model._path is not None:
|
|
17
34
|
path = Path(model._path).resolve()
|
|
18
|
-
|
|
35
|
+
uri = f"file://{path.as_posix()}"
|
|
36
|
+
if uri in model_map:
|
|
37
|
+
model_map[uri].names.append(model.name)
|
|
38
|
+
else:
|
|
39
|
+
model_map[uri] = ModelTarget(names=[model.name])
|
|
40
|
+
|
|
41
|
+
# Add standalone audits to the map
|
|
42
|
+
audit_map: t.Dict[str, AuditTarget] = {}
|
|
43
|
+
for audit in context.standalone_audits.values():
|
|
44
|
+
if audit._path is not None:
|
|
45
|
+
path = Path(audit._path).resolve()
|
|
46
|
+
uri = f"file://{path.as_posix()}"
|
|
47
|
+
if uri not in audit_map:
|
|
48
|
+
audit_map[uri] = AuditTarget(name=audit.name)
|
|
19
49
|
|
|
20
|
-
self.map =
|
|
50
|
+
self.map: t.Dict[str, t.Union[ModelTarget, AuditTarget]] = {
|
|
51
|
+
**model_map,
|
|
52
|
+
**audit_map,
|
|
53
|
+
}
|
sqlmesh/lsp/main.py
CHANGED
|
@@ -12,7 +12,7 @@ from sqlmesh._version import __version__
|
|
|
12
12
|
from sqlmesh.core.context import Context
|
|
13
13
|
from sqlmesh.core.linter.definition import AnnotatedRuleViolation
|
|
14
14
|
from sqlmesh.lsp.completions import get_sql_completions
|
|
15
|
-
from sqlmesh.lsp.context import LSPContext
|
|
15
|
+
from sqlmesh.lsp.context import LSPContext, ModelTarget
|
|
16
16
|
from sqlmesh.lsp.custom import ALL_MODELS_FEATURE, AllModelsRequest, AllModelsResponse
|
|
17
17
|
from sqlmesh.lsp.reference import get_model_definitions_for_a_path
|
|
18
18
|
|
|
@@ -91,8 +91,10 @@ class SQLMeshLanguageServer:
|
|
|
91
91
|
models = context.map[params.text_document.uri]
|
|
92
92
|
if models is None:
|
|
93
93
|
return
|
|
94
|
+
if not isinstance(models, ModelTarget):
|
|
95
|
+
return
|
|
94
96
|
self.lint_cache[params.text_document.uri] = context.context.lint_models(
|
|
95
|
-
models,
|
|
97
|
+
models.names,
|
|
96
98
|
raise_on_error=False,
|
|
97
99
|
)
|
|
98
100
|
ls.publish_diagnostics(
|
|
@@ -108,8 +110,10 @@ class SQLMeshLanguageServer:
|
|
|
108
110
|
models = context.map[params.text_document.uri]
|
|
109
111
|
if models is None:
|
|
110
112
|
return
|
|
113
|
+
if not isinstance(models, ModelTarget):
|
|
114
|
+
return
|
|
111
115
|
self.lint_cache[params.text_document.uri] = context.context.lint_models(
|
|
112
|
-
models,
|
|
116
|
+
models.names,
|
|
113
117
|
raise_on_error=False,
|
|
114
118
|
)
|
|
115
119
|
ls.publish_diagnostics(
|
|
@@ -125,8 +129,10 @@ class SQLMeshLanguageServer:
|
|
|
125
129
|
models = context.map[params.text_document.uri]
|
|
126
130
|
if models is None:
|
|
127
131
|
return
|
|
132
|
+
if not isinstance(models, ModelTarget):
|
|
133
|
+
return
|
|
128
134
|
self.lint_cache[params.text_document.uri] = context.context.lint_models(
|
|
129
|
-
models,
|
|
135
|
+
models.names,
|
|
130
136
|
raise_on_error=False,
|
|
131
137
|
)
|
|
132
138
|
ls.publish_diagnostics(
|
sqlmesh/lsp/reference.py
CHANGED
|
@@ -3,7 +3,7 @@ import typing as t
|
|
|
3
3
|
|
|
4
4
|
from sqlmesh.core.dialect import normalize_model_name
|
|
5
5
|
from sqlmesh.core.model.definition import SqlModel
|
|
6
|
-
from sqlmesh.lsp.context import LSPContext
|
|
6
|
+
from sqlmesh.lsp.context import LSPContext, ModelTarget, AuditTarget
|
|
7
7
|
from sqlglot import exp
|
|
8
8
|
|
|
9
9
|
from sqlmesh.utils.pydantic import PydanticModel
|
|
@@ -20,7 +20,7 @@ def get_model_definitions_for_a_path(
|
|
|
20
20
|
"""
|
|
21
21
|
Get the model references for a given path.
|
|
22
22
|
|
|
23
|
-
Works for models and audits.
|
|
23
|
+
Works for models and standalone audits.
|
|
24
24
|
Works for targeting sql and python models.
|
|
25
25
|
|
|
26
26
|
Steps:
|
|
@@ -31,39 +31,63 @@ def get_model_definitions_for_a_path(
|
|
|
31
31
|
- Try get_model before normalization
|
|
32
32
|
- Match to models that the model refers to
|
|
33
33
|
"""
|
|
34
|
-
# Ensure the path is a sql
|
|
34
|
+
# Ensure the path is a sql file
|
|
35
35
|
if not document_uri.endswith(".sql"):
|
|
36
36
|
return []
|
|
37
37
|
|
|
38
|
-
# Get the
|
|
39
|
-
|
|
40
|
-
if not models:
|
|
38
|
+
# Get the file info from the context map
|
|
39
|
+
if document_uri not in lint_context.map:
|
|
41
40
|
return []
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
|
|
42
|
+
file_info = lint_context.map[document_uri]
|
|
43
|
+
|
|
44
|
+
# Process based on whether it's a model or standalone audit
|
|
45
|
+
if isinstance(file_info, ModelTarget):
|
|
46
|
+
# It's a model
|
|
47
|
+
model = lint_context.context.get_model(
|
|
48
|
+
model_or_snapshot=file_info.names[0], raise_if_missing=False
|
|
49
|
+
)
|
|
50
|
+
if model is None or not isinstance(model, SqlModel):
|
|
51
|
+
return []
|
|
52
|
+
|
|
53
|
+
query = model.query
|
|
54
|
+
dialect = model.dialect
|
|
55
|
+
depends_on = model.depends_on
|
|
56
|
+
file_path = model._path
|
|
57
|
+
elif isinstance(file_info, AuditTarget):
|
|
58
|
+
# It's a standalone audit
|
|
59
|
+
audit = lint_context.context.standalone_audits.get(file_info.name)
|
|
60
|
+
if audit is None:
|
|
61
|
+
return []
|
|
62
|
+
|
|
63
|
+
query = audit.query
|
|
64
|
+
dialect = audit.dialect
|
|
65
|
+
depends_on = audit.depends_on
|
|
66
|
+
file_path = audit._path
|
|
67
|
+
else:
|
|
44
68
|
return []
|
|
45
69
|
|
|
46
70
|
# Find all possible references
|
|
47
71
|
references = []
|
|
48
|
-
|
|
72
|
+
|
|
73
|
+
# Get SQL query and find all table references
|
|
74
|
+
tables = list(query.find_all(exp.Table))
|
|
49
75
|
if len(tables) == 0:
|
|
50
76
|
return []
|
|
51
77
|
|
|
52
|
-
read_file = open(
|
|
78
|
+
read_file = open(file_path, "r").readlines()
|
|
53
79
|
|
|
54
80
|
for table in tables:
|
|
55
|
-
depends_on = model.depends_on
|
|
56
|
-
|
|
57
81
|
# Normalize the table reference
|
|
58
82
|
unaliased = table.copy()
|
|
59
83
|
if unaliased.args.get("alias") is not None:
|
|
60
84
|
unaliased.set("alias", None)
|
|
61
|
-
reference_name = unaliased.sql(dialect=
|
|
85
|
+
reference_name = unaliased.sql(dialect=dialect)
|
|
62
86
|
try:
|
|
63
87
|
normalized_reference_name = normalize_model_name(
|
|
64
88
|
reference_name,
|
|
65
89
|
default_catalog=lint_context.context.default_catalog,
|
|
66
|
-
dialect=
|
|
90
|
+
dialect=dialect,
|
|
67
91
|
)
|
|
68
92
|
if normalized_reference_name not in depends_on:
|
|
69
93
|
continue
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlmesh
|
|
3
|
-
Version: 0.180.1.
|
|
3
|
+
Version: 0.180.1.dev9
|
|
4
4
|
Summary: Next-generation data transformation framework
|
|
5
5
|
Author-email: "TobikoData Inc." <engineering@tobikodata.com>
|
|
6
6
|
License: Apache License
|
|
@@ -232,7 +232,7 @@ Requires-Dist: pydantic>=2.0.0
|
|
|
232
232
|
Requires-Dist: requests
|
|
233
233
|
Requires-Dist: rich[jupyter]
|
|
234
234
|
Requires-Dist: ruamel.yaml
|
|
235
|
-
Requires-Dist: sqlglot[rs]~=26.
|
|
235
|
+
Requires-Dist: sqlglot[rs]~=26.17.1
|
|
236
236
|
Requires-Dist: tenacity
|
|
237
237
|
Requires-Dist: time-machine
|
|
238
238
|
Requires-Dist: json-stream
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
sqlmesh/__init__.py,sha256=uPXld_xTZ2NTruSfVJ_vR_w-uAxR3T-gMXAb-EphTe8,7167
|
|
2
|
-
sqlmesh/_version.py,sha256=
|
|
2
|
+
sqlmesh/_version.py,sha256=VYRbEJ3LOEOPGpG3dWO2WeFAi5ujk2iTbCSRJC1yNkQ,528
|
|
3
3
|
sqlmesh/magics.py,sha256=7BU9ec9zE4tjvZ3hdEqwFX2VVV-CI0h06TGZo_Ssi8M,39070
|
|
4
4
|
sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -155,11 +155,11 @@ sqlmesh/integrations/github/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
|
|
|
155
155
|
sqlmesh/integrations/github/cicd/command.py,sha256=a48qtSeRM7RD3IeydJwHLAZBHRbmFdA7uHh7Yhe5a74,11301
|
|
156
156
|
sqlmesh/integrations/github/cicd/config.py,sha256=qEy0mRfPYJw1pm68UK0v1_4kZBj5QodnpIsOZ8JjZro,1838
|
|
157
157
|
sqlmesh/integrations/github/cicd/controller.py,sha256=AiEMsRW4WSVxXP_7oQSIdzBzmYPxfYDgYeOYRk9sfJA,41388
|
|
158
|
-
sqlmesh/lsp/completions.py,sha256=
|
|
159
|
-
sqlmesh/lsp/context.py,sha256=
|
|
158
|
+
sqlmesh/lsp/completions.py,sha256=ScW0H9couhfW6QckEX2djVYTClRPXpT2Hdcg1qLfUUY,3479
|
|
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=
|
|
162
|
-
sqlmesh/lsp/reference.py,sha256=
|
|
161
|
+
sqlmesh/lsp/main.py,sha256=oOZXCWLYJ722_2zLg6lTXGfw5UXo8xt78qRO6IIKZh4,13588
|
|
162
|
+
sqlmesh/lsp/reference.py,sha256=qLy6ovxcR_q7qcqDYqVbQ_5p8cpPYeBynfL7b12_PNU,6288
|
|
163
163
|
sqlmesh/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
164
164
|
sqlmesh/migrations/v0001_init.py,sha256=h8FwMYJj9_O8yGpk12guaSaGwX5A3we2GiKeHrXi15o,2048
|
|
165
165
|
sqlmesh/migrations/v0002_remove_identify.py,sha256=ZeHuodZcQzRRZX0B0Y7SSkK3qqlDuz316kmvzojeyoU,113
|
|
@@ -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.180.1.
|
|
268
|
+
sqlmesh-0.180.1.dev9.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.180.1.
|
|
386
|
-
sqlmesh-0.180.1.
|
|
387
|
-
sqlmesh-0.180.1.
|
|
388
|
-
sqlmesh-0.180.1.
|
|
389
|
-
sqlmesh-0.180.1.
|
|
385
|
+
sqlmesh-0.180.1.dev9.dist-info/METADATA,sha256=KbzT6tCNDRTRk8UqR-gygfQYKa8S4GaWDJjpMwzoEgs,25307
|
|
386
|
+
sqlmesh-0.180.1.dev9.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
|
387
|
+
sqlmesh-0.180.1.dev9.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
|
|
388
|
+
sqlmesh-0.180.1.dev9.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
|
|
389
|
+
sqlmesh-0.180.1.dev9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|