sqlmesh 0.213.1.dev1__py3-none-any.whl → 0.227.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/__init__.py +12 -2
- sqlmesh/_version.py +2 -2
- sqlmesh/cli/main.py +0 -44
- sqlmesh/cli/project_init.py +11 -2
- sqlmesh/core/_typing.py +1 -0
- sqlmesh/core/audit/definition.py +8 -2
- sqlmesh/core/config/__init__.py +1 -1
- sqlmesh/core/config/connection.py +17 -5
- sqlmesh/core/config/dbt.py +13 -0
- sqlmesh/core/config/janitor.py +12 -0
- sqlmesh/core/config/loader.py +7 -0
- sqlmesh/core/config/model.py +2 -0
- sqlmesh/core/config/root.py +3 -0
- sqlmesh/core/console.py +81 -3
- sqlmesh/core/constants.py +1 -1
- sqlmesh/core/context.py +69 -26
- sqlmesh/core/dialect.py +3 -0
- sqlmesh/core/engine_adapter/_typing.py +2 -0
- sqlmesh/core/engine_adapter/base.py +322 -22
- sqlmesh/core/engine_adapter/base_postgres.py +17 -1
- sqlmesh/core/engine_adapter/bigquery.py +146 -7
- sqlmesh/core/engine_adapter/clickhouse.py +17 -13
- sqlmesh/core/engine_adapter/databricks.py +33 -2
- sqlmesh/core/engine_adapter/fabric.py +10 -29
- sqlmesh/core/engine_adapter/mixins.py +142 -48
- sqlmesh/core/engine_adapter/mssql.py +15 -4
- sqlmesh/core/engine_adapter/mysql.py +2 -2
- sqlmesh/core/engine_adapter/postgres.py +9 -3
- sqlmesh/core/engine_adapter/redshift.py +4 -0
- sqlmesh/core/engine_adapter/risingwave.py +1 -0
- sqlmesh/core/engine_adapter/shared.py +6 -0
- sqlmesh/core/engine_adapter/snowflake.py +82 -11
- sqlmesh/core/engine_adapter/spark.py +14 -10
- sqlmesh/core/engine_adapter/trino.py +4 -2
- sqlmesh/core/environment.py +2 -0
- sqlmesh/core/janitor.py +181 -0
- sqlmesh/core/lineage.py +1 -0
- sqlmesh/core/linter/definition.py +13 -13
- sqlmesh/core/linter/rules/builtin.py +29 -0
- sqlmesh/core/macros.py +35 -13
- sqlmesh/core/model/common.py +2 -0
- sqlmesh/core/model/definition.py +82 -28
- sqlmesh/core/model/kind.py +66 -2
- sqlmesh/core/model/meta.py +108 -4
- sqlmesh/core/node.py +101 -1
- sqlmesh/core/plan/builder.py +18 -10
- sqlmesh/core/plan/common.py +199 -2
- sqlmesh/core/plan/definition.py +25 -6
- sqlmesh/core/plan/evaluator.py +75 -113
- sqlmesh/core/plan/explainer.py +90 -8
- sqlmesh/core/plan/stages.py +42 -21
- sqlmesh/core/renderer.py +78 -32
- sqlmesh/core/scheduler.py +102 -22
- sqlmesh/core/selector.py +137 -9
- sqlmesh/core/signal.py +64 -1
- sqlmesh/core/snapshot/__init__.py +2 -0
- sqlmesh/core/snapshot/definition.py +146 -34
- sqlmesh/core/snapshot/evaluator.py +689 -124
- sqlmesh/core/state_sync/__init__.py +0 -1
- sqlmesh/core/state_sync/base.py +55 -33
- sqlmesh/core/state_sync/cache.py +12 -7
- sqlmesh/core/state_sync/common.py +216 -111
- sqlmesh/core/state_sync/db/environment.py +6 -4
- sqlmesh/core/state_sync/db/facade.py +42 -24
- sqlmesh/core/state_sync/db/interval.py +27 -7
- sqlmesh/core/state_sync/db/migrator.py +34 -16
- sqlmesh/core/state_sync/db/snapshot.py +177 -169
- sqlmesh/core/table_diff.py +2 -2
- sqlmesh/core/test/context.py +2 -0
- sqlmesh/core/test/definition.py +14 -9
- sqlmesh/dbt/adapter.py +22 -16
- sqlmesh/dbt/basemodel.py +75 -56
- sqlmesh/dbt/builtin.py +116 -12
- sqlmesh/dbt/column.py +17 -5
- sqlmesh/dbt/common.py +19 -5
- sqlmesh/dbt/context.py +14 -1
- sqlmesh/dbt/loader.py +61 -9
- sqlmesh/dbt/manifest.py +174 -16
- sqlmesh/dbt/model.py +183 -85
- sqlmesh/dbt/package.py +16 -1
- sqlmesh/dbt/profile.py +3 -3
- sqlmesh/dbt/project.py +12 -7
- sqlmesh/dbt/seed.py +6 -1
- sqlmesh/dbt/source.py +13 -1
- sqlmesh/dbt/target.py +25 -6
- sqlmesh/dbt/test.py +36 -5
- sqlmesh/migrations/v0000_baseline.py +95 -0
- sqlmesh/migrations/v0061_mysql_fix_blob_text_type.py +5 -7
- sqlmesh/migrations/v0062_add_model_gateway.py +5 -1
- sqlmesh/migrations/v0063_change_signals.py +5 -3
- sqlmesh/migrations/v0064_join_when_matched_strings.py +5 -3
- sqlmesh/migrations/v0065_add_model_optimize.py +5 -1
- sqlmesh/migrations/v0066_add_auto_restatements.py +8 -3
- sqlmesh/migrations/v0067_add_tsql_date_full_precision.py +5 -1
- sqlmesh/migrations/v0068_include_unrendered_query_in_metadata_hash.py +5 -1
- sqlmesh/migrations/v0069_update_dev_table_suffix.py +5 -3
- sqlmesh/migrations/v0070_include_grains_in_metadata_hash.py +5 -1
- sqlmesh/migrations/v0071_add_dev_version_to_intervals.py +9 -5
- sqlmesh/migrations/v0072_add_environment_statements.py +5 -3
- sqlmesh/migrations/v0073_remove_symbolic_disable_restatement.py +5 -3
- sqlmesh/migrations/v0074_add_partition_by_time_column_property.py +5 -1
- sqlmesh/migrations/v0075_remove_validate_query.py +5 -3
- sqlmesh/migrations/v0076_add_cron_tz.py +5 -1
- sqlmesh/migrations/v0077_fix_column_type_hash_calculation.py +5 -1
- sqlmesh/migrations/v0078_warn_if_non_migratable_python_env.py +5 -3
- sqlmesh/migrations/v0079_add_gateway_managed_property.py +10 -5
- sqlmesh/migrations/v0080_add_batch_size_to_scd_type_2_models.py +5 -1
- sqlmesh/migrations/v0081_update_partitioned_by.py +5 -3
- sqlmesh/migrations/v0082_warn_if_incorrectly_duplicated_statements.py +5 -3
- sqlmesh/migrations/v0083_use_sql_for_scd_time_data_type_data_hash.py +5 -1
- sqlmesh/migrations/v0084_normalize_quote_when_matched_and_merge_filter.py +5 -1
- sqlmesh/migrations/v0085_deterministic_repr.py +5 -3
- sqlmesh/migrations/v0086_check_deterministic_bug.py +5 -3
- sqlmesh/migrations/v0087_normalize_blueprint_variables.py +5 -3
- sqlmesh/migrations/v0088_warn_about_variable_python_env_diffs.py +5 -3
- sqlmesh/migrations/v0089_add_virtual_environment_mode.py +5 -1
- sqlmesh/migrations/v0090_add_forward_only_column.py +9 -5
- sqlmesh/migrations/v0091_on_additive_change.py +5 -1
- sqlmesh/migrations/v0092_warn_about_dbt_data_type_diff.py +5 -3
- sqlmesh/migrations/v0093_use_raw_sql_in_fingerprint.py +5 -1
- sqlmesh/migrations/v0094_add_dev_version_and_fingerprint_columns.py +123 -0
- sqlmesh/migrations/v0095_warn_about_dbt_raw_sql_diff.py +49 -0
- sqlmesh/migrations/v0096_remove_plan_dags_table.py +13 -0
- sqlmesh/migrations/v0097_add_dbt_name_in_node.py +9 -0
- sqlmesh/migrations/{v0060_move_audits_to_model.py → v0098_add_dbt_node_info_in_node.py} +33 -16
- sqlmesh/migrations/v0099_add_last_altered_to_intervals.py +25 -0
- sqlmesh/migrations/v0100_add_grants_and_grants_target_layer.py +9 -0
- sqlmesh/utils/__init__.py +8 -1
- sqlmesh/utils/cache.py +5 -1
- sqlmesh/utils/connection_pool.py +2 -1
- sqlmesh/utils/dag.py +65 -10
- sqlmesh/utils/date.py +8 -1
- sqlmesh/utils/errors.py +8 -0
- sqlmesh/utils/jinja.py +54 -4
- sqlmesh/utils/pydantic.py +6 -6
- sqlmesh/utils/windows.py +13 -3
- {sqlmesh-0.213.1.dev1.dist-info → sqlmesh-0.227.2.dev4.dist-info}/METADATA +7 -10
- sqlmesh-0.227.2.dev4.dist-info/RECORD +370 -0
- sqlmesh_dbt/cli.py +70 -7
- sqlmesh_dbt/console.py +14 -6
- sqlmesh_dbt/operations.py +103 -24
- sqlmesh_dbt/selectors.py +39 -1
- web/client/dist/assets/{Audits-Ucsx1GzF.js → Audits-CBiYyyx-.js} +1 -1
- web/client/dist/assets/{Banner-BWDzvavM.js → Banner-DSRbUlO5.js} +1 -1
- web/client/dist/assets/{ChevronDownIcon-D2VL13Ah.js → ChevronDownIcon-MK_nrjD_.js} +1 -1
- web/client/dist/assets/{ChevronRightIcon-DWGYbf1l.js → ChevronRightIcon-CLWtT22Q.js} +1 -1
- web/client/dist/assets/{Content-DdHDZM3I.js → Content-BNuGZN5l.js} +1 -1
- web/client/dist/assets/{Content-Bikfy8fh.js → Content-CSHJyW0n.js} +1 -1
- web/client/dist/assets/{Data-CzAJH7rW.js → Data-C1oRDbLx.js} +1 -1
- web/client/dist/assets/{DataCatalog-BJF11g8f.js → DataCatalog-HXyX2-_j.js} +1 -1
- web/client/dist/assets/{Editor-s0SBpV2y.js → Editor-BDyfpUuw.js} +1 -1
- web/client/dist/assets/{Editor-DgLhgKnm.js → Editor-D0jNItwC.js} +1 -1
- web/client/dist/assets/{Errors-D0m0O1d3.js → Errors-BfuFLcPi.js} +1 -1
- web/client/dist/assets/{FileExplorer-CEv0vXkt.js → FileExplorer-BR9IE3he.js} +1 -1
- web/client/dist/assets/{Footer-BwzXn8Ew.js → Footer-CgBEtiAh.js} +1 -1
- web/client/dist/assets/{Header-6heDkEqG.js → Header-DSqR6nSO.js} +1 -1
- web/client/dist/assets/{Input-obuJsD6k.js → Input-B-oZ6fGO.js} +1 -1
- web/client/dist/assets/Lineage-DYQVwDbD.js +1 -0
- web/client/dist/assets/{ListboxShow-HM9_qyrt.js → ListboxShow-BE5-xevs.js} +1 -1
- web/client/dist/assets/{ModelLineage-zWdKo0U2.js → ModelLineage-DkIFAYo4.js} +1 -1
- web/client/dist/assets/{Models-Bcu66SRz.js → Models-D5dWr8RB.js} +1 -1
- web/client/dist/assets/{Page-BWEEQfIt.js → Page-C-XfU5BR.js} +1 -1
- web/client/dist/assets/{Plan-C4gXCqlf.js → Plan-ZEuTINBq.js} +1 -1
- web/client/dist/assets/{PlusCircleIcon-CVDO651q.js → PlusCircleIcon-DVXAHG8_.js} +1 -1
- web/client/dist/assets/{ReportErrors-BT6xFwAr.js → ReportErrors-B7FEPzMB.js} +1 -1
- web/client/dist/assets/{Root-ryJoBK4h.js → Root-8aZyhPxF.js} +1 -1
- web/client/dist/assets/{SearchList-DB04sPb9.js → SearchList-W_iT2G82.js} +1 -1
- web/client/dist/assets/{SelectEnvironment-CUYcXUu6.js → SelectEnvironment-C65jALmO.js} +1 -1
- web/client/dist/assets/{SourceList-Doo_9ZGp.js → SourceList-DSLO6nVJ.js} +1 -1
- web/client/dist/assets/{SourceListItem-D5Mj7Dly.js → SourceListItem-BHt8d9-I.js} +1 -1
- web/client/dist/assets/{SplitPane-qHmkD1qy.js → SplitPane-CViaZmw6.js} +1 -1
- web/client/dist/assets/{Tests-DH1Z74ML.js → Tests-DhaVt5t1.js} +1 -1
- web/client/dist/assets/{Welcome-DqUJUNMF.js → Welcome-DvpjH-_4.js} +1 -1
- web/client/dist/assets/context-BctCsyGb.js +71 -0
- web/client/dist/assets/{context-Dr54UHLi.js → context-DFNeGsFF.js} +1 -1
- web/client/dist/assets/{editor-DYIP1yQ4.js → editor-CcO28cqd.js} +1 -1
- web/client/dist/assets/{file-DarlIDVi.js → file-CvJN3aZO.js} +1 -1
- web/client/dist/assets/{floating-ui.react-dom-BH3TFvkM.js → floating-ui.react-dom-CjE-JNW1.js} +1 -1
- web/client/dist/assets/{help-Bl8wqaQc.js → help-DuPhjipa.js} +1 -1
- web/client/dist/assets/{index-D1sR7wpN.js → index-C-dJH7yZ.js} +1 -1
- web/client/dist/assets/{index-O3mjYpnE.js → index-Dj0i1-CA.js} +2 -2
- web/client/dist/assets/{plan-CehRrJUG.js → plan-BTRSbjKn.js} +1 -1
- web/client/dist/assets/{popover-CqgMRE0G.js → popover-_Sf0yvOI.js} +1 -1
- web/client/dist/assets/{project-6gxepOhm.js → project-BvSOI8MY.js} +1 -1
- web/client/dist/index.html +1 -1
- sqlmesh/integrations/llm.py +0 -56
- sqlmesh/migrations/v0001_init.py +0 -60
- sqlmesh/migrations/v0002_remove_identify.py +0 -5
- sqlmesh/migrations/v0003_move_batch_size.py +0 -34
- sqlmesh/migrations/v0004_environmnent_add_finalized_at.py +0 -23
- sqlmesh/migrations/v0005_create_seed_table.py +0 -24
- sqlmesh/migrations/v0006_change_seed_hash.py +0 -5
- sqlmesh/migrations/v0007_env_table_info_to_kind.py +0 -99
- sqlmesh/migrations/v0008_create_intervals_table.py +0 -38
- sqlmesh/migrations/v0009_remove_pre_post_hooks.py +0 -62
- sqlmesh/migrations/v0010_seed_hash_batch_size.py +0 -5
- sqlmesh/migrations/v0011_add_model_kind_name.py +0 -63
- sqlmesh/migrations/v0012_update_jinja_expressions.py +0 -86
- sqlmesh/migrations/v0013_serde_using_model_dialects.py +0 -87
- sqlmesh/migrations/v0014_fix_dev_intervals.py +0 -14
- sqlmesh/migrations/v0015_environment_add_promoted_snapshot_ids.py +0 -26
- sqlmesh/migrations/v0016_fix_windows_path.py +0 -59
- sqlmesh/migrations/v0017_fix_windows_seed_path.py +0 -55
- sqlmesh/migrations/v0018_rename_snapshot_model_to_node.py +0 -53
- sqlmesh/migrations/v0019_add_env_suffix_target.py +0 -28
- sqlmesh/migrations/v0020_remove_redundant_attributes_from_dbt_models.py +0 -80
- sqlmesh/migrations/v0021_fix_table_properties.py +0 -62
- sqlmesh/migrations/v0022_move_project_to_model.py +0 -54
- sqlmesh/migrations/v0023_fix_added_models_with_forward_only_parents.py +0 -65
- sqlmesh/migrations/v0024_replace_model_kind_name_enum_with_value.py +0 -55
- sqlmesh/migrations/v0025_fix_intervals_and_missing_change_category.py +0 -117
- sqlmesh/migrations/v0026_remove_dialect_from_seed.py +0 -55
- sqlmesh/migrations/v0027_minute_interval_to_five.py +0 -57
- sqlmesh/migrations/v0028_add_plan_dags_table.py +0 -29
- sqlmesh/migrations/v0029_generate_schema_types_using_dialect.py +0 -69
- sqlmesh/migrations/v0030_update_unrestorable_snapshots.py +0 -65
- sqlmesh/migrations/v0031_remove_dbt_target_fields.py +0 -65
- sqlmesh/migrations/v0032_add_sqlmesh_version.py +0 -25
- sqlmesh/migrations/v0033_mysql_fix_blob_text_type.py +0 -45
- sqlmesh/migrations/v0034_add_default_catalog.py +0 -367
- sqlmesh/migrations/v0035_add_catalog_name_override.py +0 -22
- sqlmesh/migrations/v0036_delete_plan_dags_bug_fix.py +0 -14
- sqlmesh/migrations/v0037_remove_dbt_is_incremental_macro.py +0 -61
- sqlmesh/migrations/v0038_add_expiration_ts_to_snapshot.py +0 -73
- sqlmesh/migrations/v0039_include_environment_in_plan_dag_spec.py +0 -68
- sqlmesh/migrations/v0040_add_previous_finalized_snapshots.py +0 -26
- sqlmesh/migrations/v0041_remove_hash_raw_query_attribute.py +0 -59
- sqlmesh/migrations/v0042_trim_indirect_versions.py +0 -66
- sqlmesh/migrations/v0043_fix_remove_obsolete_attributes_in_plan_dags.py +0 -61
- sqlmesh/migrations/v0044_quote_identifiers_in_model_attributes.py +0 -5
- sqlmesh/migrations/v0045_move_gateway_variable.py +0 -70
- sqlmesh/migrations/v0046_add_batch_concurrency.py +0 -8
- sqlmesh/migrations/v0047_change_scd_string_to_column.py +0 -5
- sqlmesh/migrations/v0048_drop_indirect_versions.py +0 -59
- sqlmesh/migrations/v0049_replace_identifier_with_version_in_seeds_table.py +0 -57
- sqlmesh/migrations/v0050_drop_seeds_table.py +0 -11
- sqlmesh/migrations/v0051_rename_column_descriptions.py +0 -65
- sqlmesh/migrations/v0052_add_normalize_name_in_environment_naming_info.py +0 -28
- sqlmesh/migrations/v0053_custom_model_kind_extra_attributes.py +0 -5
- sqlmesh/migrations/v0054_fix_trailing_comments.py +0 -5
- sqlmesh/migrations/v0055_add_updated_ts_unpaused_ts_ttl_ms_unrestorable_to_snapshot.py +0 -132
- sqlmesh/migrations/v0056_restore_table_indexes.py +0 -118
- sqlmesh/migrations/v0057_add_table_format.py +0 -5
- sqlmesh/migrations/v0058_add_requirements.py +0 -26
- sqlmesh/migrations/v0059_add_physical_version.py +0 -5
- sqlmesh-0.213.1.dev1.dist-info/RECORD +0 -421
- web/client/dist/assets/Lineage-D0Hgdz2v.js +0 -1
- web/client/dist/assets/context-DgX0fp2E.js +0 -68
- {sqlmesh-0.213.1.dev1.dist-info → sqlmesh-0.227.2.dev4.dist-info}/WHEEL +0 -0
- {sqlmesh-0.213.1.dev1.dist-info → sqlmesh-0.227.2.dev4.dist-info}/entry_points.txt +0 -0
- {sqlmesh-0.213.1.dev1.dist-info → sqlmesh-0.227.2.dev4.dist-info}/licenses/LICENSE +0 -0
- {sqlmesh-0.213.1.dev1.dist-info → sqlmesh-0.227.2.dev4.dist-info}/top_level.txt +0 -0
sqlmesh/core/context.py
CHANGED
|
@@ -93,7 +93,7 @@ from sqlmesh.core.plan.definition import UserProvidedFlags
|
|
|
93
93
|
from sqlmesh.core.reference import ReferenceGraph
|
|
94
94
|
from sqlmesh.core.scheduler import Scheduler, CompletionStatus
|
|
95
95
|
from sqlmesh.core.schema_loader import create_external_models_file
|
|
96
|
-
from sqlmesh.core.selector import Selector
|
|
96
|
+
from sqlmesh.core.selector import Selector, NativeSelector
|
|
97
97
|
from sqlmesh.core.snapshot import (
|
|
98
98
|
DeployabilityIndex,
|
|
99
99
|
Snapshot,
|
|
@@ -107,8 +107,8 @@ from sqlmesh.core.state_sync import (
|
|
|
107
107
|
CachingStateSync,
|
|
108
108
|
StateReader,
|
|
109
109
|
StateSync,
|
|
110
|
-
cleanup_expired_views,
|
|
111
110
|
)
|
|
111
|
+
from sqlmesh.core.janitor import cleanup_expired_views, delete_expired_snapshots
|
|
112
112
|
from sqlmesh.core.table_diff import TableDiff
|
|
113
113
|
from sqlmesh.core.test import (
|
|
114
114
|
ModelTextTestResult,
|
|
@@ -139,6 +139,7 @@ from sqlmesh.utils.errors import (
|
|
|
139
139
|
)
|
|
140
140
|
from sqlmesh.utils.config import print_config
|
|
141
141
|
from sqlmesh.utils.jinja import JinjaMacroRegistry
|
|
142
|
+
from sqlmesh.utils.windows import IS_WINDOWS, fix_windows_path
|
|
142
143
|
|
|
143
144
|
if t.TYPE_CHECKING:
|
|
144
145
|
import pandas as pd
|
|
@@ -153,6 +154,8 @@ if t.TYPE_CHECKING:
|
|
|
153
154
|
)
|
|
154
155
|
from sqlmesh.core.snapshot import Node
|
|
155
156
|
|
|
157
|
+
from sqlmesh.core.snapshot.definition import Intervals
|
|
158
|
+
|
|
156
159
|
ModelOrSnapshot = t.Union[str, Model, Snapshot]
|
|
157
160
|
NodeOrSnapshot = t.Union[str, Model, StandaloneAudit, Snapshot]
|
|
158
161
|
|
|
@@ -274,6 +277,8 @@ class ExecutionContext(BaseContext):
|
|
|
274
277
|
deployability_index: t.Optional[DeployabilityIndex] = None,
|
|
275
278
|
default_dialect: t.Optional[str] = None,
|
|
276
279
|
default_catalog: t.Optional[str] = None,
|
|
280
|
+
is_restatement: t.Optional[bool] = None,
|
|
281
|
+
parent_intervals: t.Optional[Intervals] = None,
|
|
277
282
|
variables: t.Optional[t.Dict[str, t.Any]] = None,
|
|
278
283
|
blueprint_variables: t.Optional[t.Dict[str, t.Any]] = None,
|
|
279
284
|
):
|
|
@@ -284,6 +289,8 @@ class ExecutionContext(BaseContext):
|
|
|
284
289
|
self._default_dialect = default_dialect
|
|
285
290
|
self._variables = variables or {}
|
|
286
291
|
self._blueprint_variables = blueprint_variables or {}
|
|
292
|
+
self._is_restatement = is_restatement
|
|
293
|
+
self._parent_intervals = parent_intervals
|
|
287
294
|
|
|
288
295
|
@property
|
|
289
296
|
def default_dialect(self) -> t.Optional[str]:
|
|
@@ -308,6 +315,14 @@ class ExecutionContext(BaseContext):
|
|
|
308
315
|
"""Returns the gateway name."""
|
|
309
316
|
return self.var(c.GATEWAY)
|
|
310
317
|
|
|
318
|
+
@property
|
|
319
|
+
def is_restatement(self) -> t.Optional[bool]:
|
|
320
|
+
return self._is_restatement
|
|
321
|
+
|
|
322
|
+
@property
|
|
323
|
+
def parent_intervals(self) -> t.Optional[Intervals]:
|
|
324
|
+
return self._parent_intervals
|
|
325
|
+
|
|
311
326
|
def var(self, var_name: str, default: t.Optional[t.Any] = None) -> t.Optional[t.Any]:
|
|
312
327
|
"""Returns a variable value."""
|
|
313
328
|
return self._variables.get(var_name.lower(), default)
|
|
@@ -328,6 +343,7 @@ class ExecutionContext(BaseContext):
|
|
|
328
343
|
self.deployability_index,
|
|
329
344
|
self._default_dialect,
|
|
330
345
|
self._default_catalog,
|
|
346
|
+
self._is_restatement,
|
|
331
347
|
variables=variables,
|
|
332
348
|
blueprint_variables=blueprint_variables,
|
|
333
349
|
)
|
|
@@ -368,6 +384,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
368
384
|
load: bool = True,
|
|
369
385
|
users: t.Optional[t.List[User]] = None,
|
|
370
386
|
config_loader_kwargs: t.Optional[t.Dict[str, t.Any]] = None,
|
|
387
|
+
selector: t.Optional[t.Type[Selector]] = None,
|
|
371
388
|
):
|
|
372
389
|
self.configs = (
|
|
373
390
|
config
|
|
@@ -390,6 +407,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
390
407
|
self._engine_adapter: t.Optional[EngineAdapter] = None
|
|
391
408
|
self._linters: t.Dict[str, Linter] = {}
|
|
392
409
|
self._loaded: bool = False
|
|
410
|
+
self._selector_cls = selector or NativeSelector
|
|
393
411
|
|
|
394
412
|
self.path, self.config = t.cast(t.Tuple[Path, C], next(iter(self.configs.items())))
|
|
395
413
|
|
|
@@ -587,7 +605,8 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
587
605
|
self._state_sync = self._new_state_sync()
|
|
588
606
|
|
|
589
607
|
if self._state_sync.get_versions(validate=False).schema_version == 0:
|
|
590
|
-
self.
|
|
608
|
+
self.console.log_status_update("Initializing new project state...")
|
|
609
|
+
self._state_sync.migrate()
|
|
591
610
|
self._state_sync.get_versions()
|
|
592
611
|
self._state_sync = CachingStateSync(self._state_sync) # type: ignore
|
|
593
612
|
return self._state_sync
|
|
@@ -1428,6 +1447,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1428
1447
|
explain: t.Optional[bool] = None,
|
|
1429
1448
|
ignore_cron: t.Optional[bool] = None,
|
|
1430
1449
|
min_intervals: t.Optional[int] = None,
|
|
1450
|
+
always_include_local_changes: t.Optional[bool] = None,
|
|
1431
1451
|
) -> PlanBuilder:
|
|
1432
1452
|
"""Creates a plan builder.
|
|
1433
1453
|
|
|
@@ -1466,6 +1486,8 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1466
1486
|
diff_rendered: Whether the diff should compare raw vs rendered models
|
|
1467
1487
|
min_intervals: Adjust the plan start date on a per-model basis in order to ensure at least this many intervals are covered
|
|
1468
1488
|
on every model when checking for missing intervals
|
|
1489
|
+
always_include_local_changes: Usually when restatements are present, local changes in the filesystem are ignored.
|
|
1490
|
+
However, it can be desirable to deploy changes + restatements in the same plan, so this flag overrides the default behaviour.
|
|
1469
1491
|
|
|
1470
1492
|
Returns:
|
|
1471
1493
|
The plan builder.
|
|
@@ -1582,13 +1604,20 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1582
1604
|
"Selector did not return any models. Please check your model selection and try again."
|
|
1583
1605
|
)
|
|
1584
1606
|
|
|
1607
|
+
if always_include_local_changes is None:
|
|
1608
|
+
# default behaviour - if restatements are detected; we operate entirely out of state and ignore local changes
|
|
1609
|
+
force_no_diff = restate_models is not None or (
|
|
1610
|
+
backfill_models is not None and not backfill_models
|
|
1611
|
+
)
|
|
1612
|
+
else:
|
|
1613
|
+
force_no_diff = not always_include_local_changes
|
|
1614
|
+
|
|
1585
1615
|
snapshots = self._snapshots(models_override)
|
|
1586
1616
|
context_diff = self._context_diff(
|
|
1587
1617
|
environment or c.PROD,
|
|
1588
1618
|
snapshots=snapshots,
|
|
1589
1619
|
create_from=create_from,
|
|
1590
|
-
force_no_diff=
|
|
1591
|
-
or (backfill_models is not None and not backfill_models),
|
|
1620
|
+
force_no_diff=force_no_diff,
|
|
1592
1621
|
ensure_finalized_snapshots=self.config.plan.use_finalized_state,
|
|
1593
1622
|
diff_rendered=diff_rendered,
|
|
1594
1623
|
always_recreate_environment=self.config.plan.always_recreate_environment,
|
|
@@ -1643,6 +1672,14 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1643
1672
|
elif forward_only is None:
|
|
1644
1673
|
forward_only = self.config.plan.forward_only
|
|
1645
1674
|
|
|
1675
|
+
# When handling prod restatements, only clear intervals from other model versions if we are using full virtual environments
|
|
1676
|
+
# If we are not, then there is no point, because none of the data in dev environments can be promoted by definition
|
|
1677
|
+
restate_all_snapshots = (
|
|
1678
|
+
expanded_restate_models is not None
|
|
1679
|
+
and not is_dev
|
|
1680
|
+
and self.config.virtual_environment_mode.is_full
|
|
1681
|
+
)
|
|
1682
|
+
|
|
1646
1683
|
return self.PLAN_BUILDER_TYPE(
|
|
1647
1684
|
context_diff=context_diff,
|
|
1648
1685
|
start=start,
|
|
@@ -1650,6 +1687,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1650
1687
|
execution_time=execution_time,
|
|
1651
1688
|
apply=self.apply,
|
|
1652
1689
|
restate_models=expanded_restate_models,
|
|
1690
|
+
restate_all_snapshots=restate_all_snapshots,
|
|
1653
1691
|
backfill_models=backfill_models,
|
|
1654
1692
|
no_gaps=no_gaps,
|
|
1655
1693
|
skip_backfill=skip_backfill,
|
|
@@ -1676,6 +1714,11 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1676
1714
|
end_override_per_model=max_interval_end_per_model,
|
|
1677
1715
|
console=self.console,
|
|
1678
1716
|
user_provided_flags=user_provided_flags,
|
|
1717
|
+
selected_models={
|
|
1718
|
+
dbt_unique_id
|
|
1719
|
+
for model in model_selector.expand_model_selections(select_models or "*")
|
|
1720
|
+
if (dbt_unique_id := snapshots[model].node.dbt_unique_id)
|
|
1721
|
+
},
|
|
1679
1722
|
explain=explain or False,
|
|
1680
1723
|
ignore_cron=ignore_cron or False,
|
|
1681
1724
|
)
|
|
@@ -2236,6 +2279,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
2236
2279
|
snapshot=snapshot,
|
|
2237
2280
|
start=start,
|
|
2238
2281
|
end=end,
|
|
2282
|
+
execution_time=execution_time,
|
|
2239
2283
|
snapshots=self.snapshots,
|
|
2240
2284
|
):
|
|
2241
2285
|
audit_id = f"{audit_result.audit.name}"
|
|
@@ -2355,7 +2399,6 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
2355
2399
|
self._load_materializations()
|
|
2356
2400
|
try:
|
|
2357
2401
|
self._new_state_sync().migrate(
|
|
2358
|
-
default_catalog=self.default_catalog,
|
|
2359
2402
|
promoted_snapshots_only=self.config.migration.promoted_snapshots_only,
|
|
2360
2403
|
)
|
|
2361
2404
|
except Exception as e:
|
|
@@ -2557,12 +2600,15 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
2557
2600
|
)
|
|
2558
2601
|
|
|
2559
2602
|
def clear_caches(self) -> None:
|
|
2560
|
-
for path in self.configs
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2603
|
+
paths_to_remove = [path / c.CACHE for path in self.configs]
|
|
2604
|
+
paths_to_remove.append(self.cache_dir)
|
|
2605
|
+
|
|
2606
|
+
if IS_WINDOWS:
|
|
2607
|
+
paths_to_remove = [fix_windows_path(path) for path in paths_to_remove]
|
|
2608
|
+
|
|
2609
|
+
for path in paths_to_remove:
|
|
2610
|
+
if path.exists():
|
|
2611
|
+
rmtree(path)
|
|
2566
2612
|
|
|
2567
2613
|
if isinstance(self._state_sync, CachingStateSync):
|
|
2568
2614
|
self._state_sync.clear_cache()
|
|
@@ -2819,19 +2865,14 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
2819
2865
|
# Clean up expired environments by removing their views and schemas
|
|
2820
2866
|
self._cleanup_environments(current_ts=current_ts)
|
|
2821
2867
|
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
on_complete=self.console.update_cleanup_progress,
|
|
2868
|
+
delete_expired_snapshots(
|
|
2869
|
+
self.state_sync,
|
|
2870
|
+
self.snapshot_evaluator,
|
|
2871
|
+
current_ts=current_ts,
|
|
2872
|
+
ignore_ttl=ignore_ttl,
|
|
2873
|
+
console=self.console,
|
|
2874
|
+
batch_size=self.config.janitor.expired_snapshots_batch_size,
|
|
2830
2875
|
)
|
|
2831
|
-
|
|
2832
|
-
# Delete the expired snapshot records from the state sync
|
|
2833
|
-
self.state_sync.delete_expired_snapshots(ignore_ttl=ignore_ttl, current_ts=current_ts)
|
|
2834
|
-
|
|
2835
2876
|
self.state_sync.compact_intervals()
|
|
2836
2877
|
|
|
2837
2878
|
def _cleanup_environments(self, current_ts: t.Optional[int] = None) -> None:
|
|
@@ -2869,7 +2910,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
2869
2910
|
def _new_selector(
|
|
2870
2911
|
self, models: t.Optional[UniqueKeyDict[str, Model]] = None, dag: t.Optional[DAG[str]] = None
|
|
2871
2912
|
) -> Selector:
|
|
2872
|
-
return
|
|
2913
|
+
return self._selector_cls(
|
|
2873
2914
|
self.state_reader,
|
|
2874
2915
|
models=models or self._models,
|
|
2875
2916
|
context_path=self.path,
|
|
@@ -3130,7 +3171,9 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
3130
3171
|
found_error = False
|
|
3131
3172
|
|
|
3132
3173
|
model_list = (
|
|
3133
|
-
list(self.get_model(model) for model in models)
|
|
3174
|
+
list(self.get_model(model, raise_if_missing=True) for model in models)
|
|
3175
|
+
if models
|
|
3176
|
+
else self.models.values()
|
|
3134
3177
|
)
|
|
3135
3178
|
all_violations = []
|
|
3136
3179
|
for model in model_list:
|
sqlmesh/core/dialect.py
CHANGED
|
@@ -174,6 +174,7 @@ def _parse_id_var(
|
|
|
174
174
|
|
|
175
175
|
while (
|
|
176
176
|
identifier
|
|
177
|
+
and not identifier.args.get("quoted")
|
|
177
178
|
and self._is_connected()
|
|
178
179
|
and (
|
|
179
180
|
self._match_texts(("{", SQLMESH_MACRO_PREFIX))
|
|
@@ -349,6 +350,7 @@ def _parse_select(
|
|
|
349
350
|
parse_subquery_alias: bool = True,
|
|
350
351
|
parse_set_operation: bool = True,
|
|
351
352
|
consume_pipe: bool = True,
|
|
353
|
+
from_: t.Optional[exp.From] = None,
|
|
352
354
|
) -> t.Optional[exp.Expression]:
|
|
353
355
|
select = self.__parse_select( # type: ignore
|
|
354
356
|
nested=nested,
|
|
@@ -356,6 +358,7 @@ def _parse_select(
|
|
|
356
358
|
parse_subquery_alias=parse_subquery_alias,
|
|
357
359
|
parse_set_operation=parse_set_operation,
|
|
358
360
|
consume_pipe=consume_pipe,
|
|
361
|
+
from_=from_,
|
|
359
362
|
)
|
|
360
363
|
|
|
361
364
|
if (
|