sqlmesh 0.206.2.dev2__py3-none-any.whl → 0.206.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.206.2.dev2'
21
- __version_tuple__ = version_tuple = (0, 206, 2, 'dev2')
20
+ __version__ = version = '0.206.2.dev4'
21
+ __version_tuple__ = version_tuple = (0, 206, 2, 'dev4')
sqlmesh/core/dialect.py CHANGED
@@ -13,6 +13,7 @@ from functools import lru_cache
13
13
  from sqlglot import Dialect, Generator, ParseError, Parser, Tokenizer, TokenType, exp
14
14
  from sqlglot.dialects.dialect import DialectType
15
15
  from sqlglot.dialects import DuckDB, Snowflake
16
+ import sqlglot.dialects.athena as athena
16
17
  from sqlglot.helper import seq_get
17
18
  from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
18
19
  from sqlglot.optimizer.qualify_columns import quote_identifiers
@@ -1014,6 +1015,14 @@ def extend_sqlglot() -> None:
1014
1015
  generators = {Generator}
1015
1016
 
1016
1017
  for dialect in Dialect.classes.values():
1018
+ # Athena picks a different Tokenizer / Parser / Generator depending on the query
1019
+ # so this ensures that the extra ones it defines are also extended
1020
+ if dialect == athena.Athena:
1021
+ tokenizers.add(athena._TrinoTokenizer)
1022
+ parsers.add(athena._TrinoParser)
1023
+ generators.add(athena._TrinoGenerator)
1024
+ generators.add(athena._HiveGenerator)
1025
+
1017
1026
  if hasattr(dialect, "Tokenizer"):
1018
1027
  tokenizers.add(dialect.Tokenizer)
1019
1028
  if hasattr(dialect, "Parser"):
@@ -157,7 +157,7 @@ def _add_variables_to_python_env(
157
157
 
158
158
  if blueprint_variables:
159
159
  blueprint_variables = {
160
- k: SqlValue(sql=v.sql(dialect=dialect)) if isinstance(v, exp.Expression) else v
160
+ k.lower(): SqlValue(sql=v.sql(dialect=dialect)) if isinstance(v, exp.Expression) else v
161
161
  for k, v in blueprint_variables.items()
162
162
  }
163
163
  python_env[c.SQLMESH_BLUEPRINT_VARS] = Executable.value(
@@ -0,0 +1,138 @@
1
+ """
2
+ Normalizes blueprint variables, so Customer_Field is stored as customer_field in the `python_env`:
3
+
4
+ MODEL (
5
+ ...
6
+ blueprints (
7
+ Customer_Field := 1
8
+ )
9
+ );
10
+
11
+ SELECT
12
+ @customer_field AS col
13
+ """
14
+
15
+ import json
16
+ import logging
17
+ from dataclasses import dataclass
18
+
19
+ from sqlglot import exp
20
+ from sqlmesh.core.console import get_console
21
+ from sqlmesh.utils.migration import index_text_type, blob_text_type
22
+
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ SQLMESH_BLUEPRINT_VARS = "__sqlmesh__blueprint__vars__"
28
+
29
+
30
+ # Make sure `SqlValue` is defined so it can be used by `eval` call in the migration
31
+ @dataclass
32
+ class SqlValue:
33
+ """A SQL string representing a generated SQLGlot AST."""
34
+
35
+ sql: str
36
+
37
+
38
+ def migrate(state_sync, **kwargs): # type: ignore
39
+ import pandas as pd
40
+
41
+ engine_adapter = state_sync.engine_adapter
42
+ schema = state_sync.schema
43
+ snapshots_table = "_snapshots"
44
+ if schema:
45
+ snapshots_table = f"{schema}.{snapshots_table}"
46
+
47
+ migration_needed = False
48
+ new_snapshots = []
49
+
50
+ for (
51
+ name,
52
+ identifier,
53
+ version,
54
+ snapshot,
55
+ kind_name,
56
+ updated_ts,
57
+ unpaused_ts,
58
+ ttl_ms,
59
+ unrestorable,
60
+ ) in engine_adapter.fetchall(
61
+ exp.select(
62
+ "name",
63
+ "identifier",
64
+ "version",
65
+ "snapshot",
66
+ "kind_name",
67
+ "updated_ts",
68
+ "unpaused_ts",
69
+ "ttl_ms",
70
+ "unrestorable",
71
+ ).from_(snapshots_table),
72
+ quote_identifiers=True,
73
+ ):
74
+ parsed_snapshot = json.loads(snapshot)
75
+ node = parsed_snapshot["node"]
76
+ python_env = node.get("python_env") or {}
77
+
78
+ migrate_snapshot = False
79
+
80
+ if blueprint_vars_executable := python_env.get(SQLMESH_BLUEPRINT_VARS):
81
+ blueprint_vars = eval(blueprint_vars_executable["payload"])
82
+
83
+ for var, value in dict(blueprint_vars).items():
84
+ lowercase_var = var.lower()
85
+ if var != lowercase_var:
86
+ if lowercase_var in blueprint_vars:
87
+ get_console().log_warning(
88
+ "SQLMesh is unable to fully migrate the state database, because the "
89
+ f"model '{node['name']}' contains two blueprint variables ('{var}' and "
90
+ f"'{lowercase_var}') that resolve to the same value ('{lowercase_var}'). "
91
+ "This may result in unexpected changes being reported by the next "
92
+ "`sqlmesh plan` command. If this happens, consider renaming either variable, "
93
+ "so that the lowercase version of their names are different."
94
+ )
95
+ else:
96
+ del blueprint_vars[var]
97
+ blueprint_vars[lowercase_var] = value
98
+ migrate_snapshot = True
99
+
100
+ if migrate_snapshot:
101
+ migration_needed = True
102
+ blueprint_vars_executable["payload"] = repr(blueprint_vars)
103
+
104
+ new_snapshots.append(
105
+ {
106
+ "name": name,
107
+ "identifier": identifier,
108
+ "version": version,
109
+ "snapshot": json.dumps(parsed_snapshot),
110
+ "kind_name": kind_name,
111
+ "updated_ts": updated_ts,
112
+ "unpaused_ts": unpaused_ts,
113
+ "ttl_ms": ttl_ms,
114
+ "unrestorable": unrestorable,
115
+ }
116
+ )
117
+
118
+ if migration_needed and new_snapshots:
119
+ engine_adapter.delete_from(snapshots_table, "TRUE")
120
+
121
+ index_type = index_text_type(engine_adapter.dialect)
122
+ blob_type = blob_text_type(engine_adapter.dialect)
123
+
124
+ engine_adapter.insert_append(
125
+ snapshots_table,
126
+ pd.DataFrame(new_snapshots),
127
+ columns_to_types={
128
+ "name": exp.DataType.build(index_type),
129
+ "identifier": exp.DataType.build(index_type),
130
+ "version": exp.DataType.build(index_type),
131
+ "snapshot": exp.DataType.build(blob_type),
132
+ "kind_name": exp.DataType.build("text"),
133
+ "updated_ts": exp.DataType.build("bigint"),
134
+ "unpaused_ts": exp.DataType.build("bigint"),
135
+ "ttl_ms": exp.DataType.build("bigint"),
136
+ "unrestorable": exp.DataType.build("boolean"),
137
+ },
138
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.206.2.dev2
3
+ Version: 0.206.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=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
2
- sqlmesh/_version.py,sha256=ODmuGfXnsHOG7yOzSoA-XJjd_1OkCpWgVFsH_K0ggDM,528
2
+ sqlmesh/_version.py,sha256=UjOy4yonGrNWHc4ceruDSYcy8OBbaR2th5VIqKYuU8E,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
@@ -15,7 +15,7 @@ sqlmesh/core/console.py,sha256=ovjM75l1A2rAi-ud3ovsIKSGwF9TsGYTK8NvokbCdL4,16611
15
15
  sqlmesh/core/constants.py,sha256=gUABXWYgH_XOSbaZAJsR5o1dmA61JDCvBDyxqqXX3LM,2630
16
16
  sqlmesh/core/context.py,sha256=SkTNrp9TUNx469_mWkemhMk4leGDtmblBIWE7S64sk8,127598
17
17
  sqlmesh/core/context_diff.py,sha256=_Ur55fGLJ58Icsp44I4pVhdi7_JHiHq45mWIco9oFzk,21792
18
- sqlmesh/core/dialect.py,sha256=ELBtB8ft0OyalhgqQ1CUnn26xJxLDah2SP1v8kh_FB8,50903
18
+ sqlmesh/core/dialect.py,sha256=lJHcE7D6GvYs1tzbexJb1mi4gltsMUzHeOrhN4ObIdo,51343
19
19
  sqlmesh/core/environment.py,sha256=odus40R-YzdQdS_IiUq_tFouUXIhnpwmNwo8dE8Aw1k,13041
20
20
  sqlmesh/core/lineage.py,sha256=zjB0Zfamo2Fja2r5SSZPMbrEKTXr1WjozZPVqvxdybI,3143
21
21
  sqlmesh/core/loader.py,sha256=N9KPfa-R4BCId7BCLujMkIKwXgxnftC-dD0rP0cpv1w,41088
@@ -86,7 +86,7 @@ sqlmesh/core/metric/definition.py,sha256=Yd5aVgsZCDPJ43aGP7WqtzZOuuSUtB8uJGVA6Jw
86
86
  sqlmesh/core/metric/rewriter.py,sha256=GiSTHfn2kinqCfNPYgZPRk93JFLzVaaejHtHDQ0yXZI,7326
87
87
  sqlmesh/core/model/__init__.py,sha256=C8GRZ53xuXEA9hQv3BQS9pNNyd9rZ06R_B96UYGhDu4,1644
88
88
  sqlmesh/core/model/cache.py,sha256=csun0RJguHzKX6-qITcOs4fVP4f8_Ts8qiUVV4sHY6Q,7869
89
- sqlmesh/core/model/common.py,sha256=mUVJZ1otbcY9IPqeJQWxZOgv_2QnYEEKdFwcPvZGe9c,17961
89
+ sqlmesh/core/model/common.py,sha256=Gt1nBdbILfR52Rhq2KxF0EMGkB3J5zfk6UH7ecLpMZI,17969
90
90
  sqlmesh/core/model/decorator.py,sha256=wUUg5t0K559tV9Pqt6FE2EWXt5TPGb4wF2Yg4B4hX4w,9251
91
91
  sqlmesh/core/model/definition.py,sha256=UsRFDlO3A5so4HM2_x6M0sdTR-VlTIxw1d-T_gxS_9Q,113897
92
92
  sqlmesh/core/model/kind.py,sha256=8Dp8yiTiXltboZWrB2FJ-LQ3zx4Fv_5Tj0KdUIPwCHI,36358
@@ -263,6 +263,7 @@ sqlmesh/migrations/v0083_use_sql_for_scd_time_data_type_data_hash.py,sha256=0r-S
263
263
  sqlmesh/migrations/v0084_normalize_quote_when_matched_and_merge_filter.py,sha256=w1TbhvB98czuq5VZxsfcQE2w7o-nd96aKEIG-M1dn6A,329
264
264
  sqlmesh/migrations/v0085_deterministic_repr.py,sha256=mkbZV0rzXJ5bmN1Y75kFI9T6gbnx_sy-zn_UzbOL1Sg,4265
265
265
  sqlmesh/migrations/v0086_check_deterministic_bug.py,sha256=WiYcmhQD434GXWiiakQtcy9ESmB35spXMltV43nvU7Q,2953
266
+ sqlmesh/migrations/v0087_normalize_blueprint_variables.py,sha256=GI6KKA-6PtONUoOnyvLpRTUmPjbpa-CKhDa0iqJW01U,4421
266
267
  sqlmesh/schedulers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
267
268
  sqlmesh/utils/__init__.py,sha256=51VqA2etTZ6kX54250s1hN5ui7D89OeUTUQ9kgMze7s,11554
268
269
  sqlmesh/utils/aws.py,sha256=krxyhrKtsMJDEjT567UbGZogjJ9JRHkvAV-Cg3FVndM,1062
@@ -287,7 +288,7 @@ sqlmesh/utils/pydantic.py,sha256=o_NsXbIpDqNpUA1Uc5xF0ZzoXQYYB0DfHwdRxBwXPNk,120
287
288
  sqlmesh/utils/rich.py,sha256=cwQ5nJ6sgz64xHtoh6_ec7ReV5YpsOGhMtUJnwoRfEI,3549
288
289
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
289
290
  sqlmesh/utils/yaml.py,sha256=hvo5lmybYLcIx4p6CQwufS8X4MbwS60lEBnCmYJCXmU,2336
290
- sqlmesh-0.206.2.dev2.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
291
+ sqlmesh-0.206.2.dev4.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
291
292
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
292
293
  web/client/dist/index.html,sha256=SXykdSRNgrT1k6I2dPZPEfpxPjIsi8-yVFijt-naSA4,5472
293
294
  web/client/dist/assets/Audits-Jm353fhk.js,sha256=ry6b5IKT3hLAfD5C3T2BqxulfauEV0n0YZ2vsP4eQ_U,1041
@@ -405,8 +406,8 @@ web/server/api/endpoints/models.py,sha256=kwj0s7uve3iZSMfmjkoPVMFMeY1sD0peTeyrWf
405
406
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
406
407
  web/server/api/endpoints/plan.py,sha256=bbbY50W_2MsZSTxOHWMKz0tbIm75nsRSlPy8GI2fg9Q,9306
407
408
  web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
408
- sqlmesh-0.206.2.dev2.dist-info/METADATA,sha256=qajqCyJXBIv3CUyhI_xZDP41Mo7zRlMflgxEW0Hs1fs,26685
409
- sqlmesh-0.206.2.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
410
- sqlmesh-0.206.2.dev2.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
411
- sqlmesh-0.206.2.dev2.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
412
- sqlmesh-0.206.2.dev2.dist-info/RECORD,,
409
+ sqlmesh-0.206.2.dev4.dist-info/METADATA,sha256=PoP8Fc1vGMvf1E7QwezSWn_BL8ZUVCRuTJjdIVu6lcU,26685
410
+ sqlmesh-0.206.2.dev4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
411
+ sqlmesh-0.206.2.dev4.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
412
+ sqlmesh-0.206.2.dev4.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
413
+ sqlmesh-0.206.2.dev4.dist-info/RECORD,,