sqlmesh 0.199.1.dev17__py3-none-any.whl → 0.199.1.dev19__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/cli/main.py +5 -0
- sqlmesh/core/console.py +2 -2
- sqlmesh/core/context.py +113 -9
- sqlmesh/core/node.py +3 -0
- sqlmesh/core/plan/builder.py +17 -8
- sqlmesh/core/plan/definition.py +8 -4
- sqlmesh/core/plan/evaluator.py +2 -1
- sqlmesh/core/plan/stages.py +2 -1
- sqlmesh/core/scheduler.py +33 -16
- sqlmesh/core/snapshot/definition.py +16 -11
- {sqlmesh-0.199.1.dev17.dist-info → sqlmesh-0.199.1.dev19.dist-info}/METADATA +1 -1
- {sqlmesh-0.199.1.dev17.dist-info → sqlmesh-0.199.1.dev19.dist-info}/RECORD +17 -17
- {sqlmesh-0.199.1.dev17.dist-info → sqlmesh-0.199.1.dev19.dist-info}/WHEEL +0 -0
- {sqlmesh-0.199.1.dev17.dist-info → sqlmesh-0.199.1.dev19.dist-info}/entry_points.txt +0 -0
- {sqlmesh-0.199.1.dev17.dist-info → sqlmesh-0.199.1.dev19.dist-info}/licenses/LICENSE +0 -0
- {sqlmesh-0.199.1.dev17.dist-info → sqlmesh-0.199.1.dev19.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.199.1.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 199, 1, '
|
|
20
|
+
__version__ = version = '0.199.1.dev19'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 199, 1, 'dev19')
|
sqlmesh/cli/main.py
CHANGED
|
@@ -520,6 +520,11 @@ def diff(ctx: click.Context, environment: t.Optional[str] = None) -> None:
|
|
|
520
520
|
help="Explain the plan instead of applying it.",
|
|
521
521
|
default=None,
|
|
522
522
|
)
|
|
523
|
+
@click.option(
|
|
524
|
+
"--min-intervals",
|
|
525
|
+
default=0,
|
|
526
|
+
help="For every model, ensure at least this many intervals are covered by a missing intervals check regardless of the plan start date",
|
|
527
|
+
)
|
|
523
528
|
@opt.verbose
|
|
524
529
|
@click.pass_context
|
|
525
530
|
@error_handler
|
sqlmesh/core/console.py
CHANGED
|
@@ -2073,8 +2073,8 @@ class TerminalConsole(Console):
|
|
|
2073
2073
|
if not plan_builder.override_end:
|
|
2074
2074
|
if plan.provided_end:
|
|
2075
2075
|
blank_meaning = f"'{time_like_to_str(plan.provided_end)}'"
|
|
2076
|
-
elif plan.
|
|
2077
|
-
max_end = max(plan.
|
|
2076
|
+
elif plan.end_override_per_model:
|
|
2077
|
+
max_end = max(plan.end_override_per_model.values())
|
|
2078
2078
|
blank_meaning = f"'{time_like_to_str(max_end)}'"
|
|
2079
2079
|
else:
|
|
2080
2080
|
blank_meaning = "now"
|
sqlmesh/core/context.py
CHANGED
|
@@ -46,6 +46,7 @@ from itertools import chain
|
|
|
46
46
|
from pathlib import Path
|
|
47
47
|
from shutil import rmtree
|
|
48
48
|
from types import MappingProxyType
|
|
49
|
+
from datetime import datetime
|
|
49
50
|
|
|
50
51
|
from sqlglot import Dialect, exp
|
|
51
52
|
from sqlglot.helper import first
|
|
@@ -125,6 +126,8 @@ from sqlmesh.utils.date import (
|
|
|
125
126
|
format_tz_datetime,
|
|
126
127
|
now_timestamp,
|
|
127
128
|
now,
|
|
129
|
+
to_datetime,
|
|
130
|
+
make_exclusive,
|
|
128
131
|
)
|
|
129
132
|
from sqlmesh.utils.errors import (
|
|
130
133
|
CircuitBreakerError,
|
|
@@ -1222,6 +1225,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1222
1225
|
diff_rendered: t.Optional[bool] = None,
|
|
1223
1226
|
skip_linter: t.Optional[bool] = None,
|
|
1224
1227
|
explain: t.Optional[bool] = None,
|
|
1228
|
+
min_intervals: t.Optional[int] = None,
|
|
1225
1229
|
) -> Plan:
|
|
1226
1230
|
"""Interactively creates a plan.
|
|
1227
1231
|
|
|
@@ -1268,6 +1272,8 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1268
1272
|
diff_rendered: Whether the diff should compare raw vs rendered models
|
|
1269
1273
|
skip_linter: Linter runs by default so this will skip it if enabled
|
|
1270
1274
|
explain: Whether to explain the plan instead of applying it.
|
|
1275
|
+
min_intervals: Adjust the plan start date on a per-model basis in order to ensure at least this many intervals are covered
|
|
1276
|
+
on every model when checking for missing intervals
|
|
1271
1277
|
|
|
1272
1278
|
Returns:
|
|
1273
1279
|
The populated Plan object.
|
|
@@ -1296,6 +1302,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1296
1302
|
diff_rendered=diff_rendered,
|
|
1297
1303
|
skip_linter=skip_linter,
|
|
1298
1304
|
explain=explain,
|
|
1305
|
+
min_intervals=min_intervals,
|
|
1299
1306
|
)
|
|
1300
1307
|
|
|
1301
1308
|
plan = plan_builder.build()
|
|
@@ -1345,6 +1352,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1345
1352
|
diff_rendered: t.Optional[bool] = None,
|
|
1346
1353
|
skip_linter: t.Optional[bool] = None,
|
|
1347
1354
|
explain: t.Optional[bool] = None,
|
|
1355
|
+
min_intervals: t.Optional[int] = None,
|
|
1348
1356
|
) -> PlanBuilder:
|
|
1349
1357
|
"""Creates a plan builder.
|
|
1350
1358
|
|
|
@@ -1381,6 +1389,8 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1381
1389
|
enable_preview: Indicates whether to enable preview for forward-only models in development environments.
|
|
1382
1390
|
run: Whether to run latest intervals as part of the plan application.
|
|
1383
1391
|
diff_rendered: Whether the diff should compare raw vs rendered models
|
|
1392
|
+
min_intervals: Adjust the plan start date on a per-model basis in order to ensure at least this many intervals are covered
|
|
1393
|
+
on every model when checking for missing intervals
|
|
1384
1394
|
|
|
1385
1395
|
Returns:
|
|
1386
1396
|
The plan builder.
|
|
@@ -1408,6 +1418,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1408
1418
|
"run": run,
|
|
1409
1419
|
"diff_rendered": diff_rendered,
|
|
1410
1420
|
"skip_linter": skip_linter,
|
|
1421
|
+
"min_intervals": min_intervals,
|
|
1411
1422
|
}
|
|
1412
1423
|
user_provided_flags: t.Dict[str, UserProvidedFlags] = {
|
|
1413
1424
|
k: v for k, v in kwargs.items() if v is not None
|
|
@@ -1530,6 +1541,16 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1530
1541
|
# Refresh snapshot intervals to ensure that they are up to date with values reflected in the max_interval_end_per_model.
|
|
1531
1542
|
self.state_sync.refresh_snapshot_intervals(context_diff.snapshots.values())
|
|
1532
1543
|
|
|
1544
|
+
start_override_per_model = self._calculate_start_override_per_model(
|
|
1545
|
+
min_intervals,
|
|
1546
|
+
start or default_start,
|
|
1547
|
+
end or default_end,
|
|
1548
|
+
execution_time or now(),
|
|
1549
|
+
backfill_models,
|
|
1550
|
+
snapshots,
|
|
1551
|
+
max_interval_end_per_model,
|
|
1552
|
+
)
|
|
1553
|
+
|
|
1533
1554
|
return self.PLAN_BUILDER_TYPE(
|
|
1534
1555
|
context_diff=context_diff,
|
|
1535
1556
|
start=start,
|
|
@@ -1560,7 +1581,8 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
1560
1581
|
),
|
|
1561
1582
|
end_bounded=not run,
|
|
1562
1583
|
ensure_finalized_snapshots=self.config.plan.use_finalized_state,
|
|
1563
|
-
|
|
1584
|
+
start_override_per_model=start_override_per_model,
|
|
1585
|
+
end_override_per_model=max_interval_end_per_model,
|
|
1564
1586
|
console=self.console,
|
|
1565
1587
|
user_provided_flags=user_provided_flags,
|
|
1566
1588
|
explain=explain or False,
|
|
@@ -2850,7 +2872,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
2850
2872
|
def _get_plan_default_start_end(
|
|
2851
2873
|
self,
|
|
2852
2874
|
snapshots: t.Dict[str, Snapshot],
|
|
2853
|
-
max_interval_end_per_model: t.Dict[str,
|
|
2875
|
+
max_interval_end_per_model: t.Dict[str, datetime],
|
|
2854
2876
|
backfill_models: t.Optional[t.Set[str]],
|
|
2855
2877
|
modified_model_names: t.Set[str],
|
|
2856
2878
|
execution_time: t.Optional[TimeLike] = None,
|
|
@@ -2858,7 +2880,7 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
2858
2880
|
if not max_interval_end_per_model:
|
|
2859
2881
|
return None, None
|
|
2860
2882
|
|
|
2861
|
-
default_end = max(max_interval_end_per_model.values())
|
|
2883
|
+
default_end = to_timestamp(max(max_interval_end_per_model.values()))
|
|
2862
2884
|
default_start: t.Optional[int] = None
|
|
2863
2885
|
# Infer the default start by finding the smallest interval start that corresponds to the default end.
|
|
2864
2886
|
for model_name in backfill_models or modified_model_names or max_interval_end_per_model:
|
|
@@ -2887,19 +2909,101 @@ class GenericContext(BaseContext, t.Generic[C]):
|
|
|
2887
2909
|
|
|
2888
2910
|
return default_start, default_end
|
|
2889
2911
|
|
|
2912
|
+
def _calculate_start_override_per_model(
|
|
2913
|
+
self,
|
|
2914
|
+
min_intervals: t.Optional[int],
|
|
2915
|
+
plan_start: t.Optional[TimeLike],
|
|
2916
|
+
plan_end: t.Optional[TimeLike],
|
|
2917
|
+
plan_execution_time: TimeLike,
|
|
2918
|
+
backfill_model_fqns: t.Optional[t.Set[str]],
|
|
2919
|
+
snapshots_by_model_fqn: t.Dict[str, Snapshot],
|
|
2920
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]],
|
|
2921
|
+
) -> t.Dict[str, datetime]:
|
|
2922
|
+
if not min_intervals or not backfill_model_fqns or not plan_start:
|
|
2923
|
+
# If there are no models to backfill, there are no intervals to consider for backfill, so we dont need to consider a minimum number
|
|
2924
|
+
# If the plan doesnt have a start date, all intervals are considered already so we dont need to consider a minimum number
|
|
2925
|
+
# If we dont have a minimum number of intervals to consider, then we dont need to adjust the start date on a per-model basis
|
|
2926
|
+
return {}
|
|
2927
|
+
|
|
2928
|
+
start_overrides: t.Dict[str, datetime] = {}
|
|
2929
|
+
end_override_per_model = end_override_per_model or {}
|
|
2930
|
+
|
|
2931
|
+
plan_execution_time_dt = to_datetime(plan_execution_time)
|
|
2932
|
+
plan_start_dt = to_datetime(plan_start, relative_base=plan_execution_time_dt)
|
|
2933
|
+
plan_end_dt = to_datetime(
|
|
2934
|
+
plan_end or plan_execution_time_dt, relative_base=plan_execution_time_dt
|
|
2935
|
+
)
|
|
2936
|
+
|
|
2937
|
+
# we need to take the DAG into account so that parent models can be expanded to cover at least as much as their children
|
|
2938
|
+
# for example, A(hourly) <- B(daily)
|
|
2939
|
+
# if min_intervals=1, A would have 1 hour and B would have 1 day
|
|
2940
|
+
# but B depends on A so in order for B to have 1 valid day, A needs to be expanded to 24 hours
|
|
2941
|
+
backfill_dag: DAG[str] = DAG()
|
|
2942
|
+
for fqn in backfill_model_fqns:
|
|
2943
|
+
backfill_dag.add(
|
|
2944
|
+
fqn,
|
|
2945
|
+
[
|
|
2946
|
+
p.name
|
|
2947
|
+
for p in snapshots_by_model_fqn[fqn].parents
|
|
2948
|
+
if p.name in backfill_model_fqns
|
|
2949
|
+
],
|
|
2950
|
+
)
|
|
2951
|
+
|
|
2952
|
+
# start from the leaf nodes and work back towards the root because the min_start at the root node is determined by the calculated starts in the leaf nodes
|
|
2953
|
+
reversed_dag = backfill_dag.reversed
|
|
2954
|
+
graph = reversed_dag.graph
|
|
2955
|
+
|
|
2956
|
+
for model_fqn in reversed_dag:
|
|
2957
|
+
# Get the earliest start from all immediate children of this snapshot
|
|
2958
|
+
# this works because topological ordering guarantees that they've already been visited
|
|
2959
|
+
# and we always set a start override
|
|
2960
|
+
min_child_start = min(
|
|
2961
|
+
[start_overrides[immediate_child_fqn] for immediate_child_fqn in graph[model_fqn]],
|
|
2962
|
+
default=plan_start_dt,
|
|
2963
|
+
)
|
|
2964
|
+
|
|
2965
|
+
snapshot = snapshots_by_model_fqn.get(model_fqn)
|
|
2966
|
+
|
|
2967
|
+
if not snapshot:
|
|
2968
|
+
continue
|
|
2969
|
+
|
|
2970
|
+
starting_point = end_override_per_model.get(model_fqn, plan_end_dt)
|
|
2971
|
+
if node_end := snapshot.node.end:
|
|
2972
|
+
# if we dont do this, if the node end is a *date* (as opposed to a timestamp)
|
|
2973
|
+
# we end up incorrectly winding back an extra day
|
|
2974
|
+
node_end_dt = make_exclusive(node_end)
|
|
2975
|
+
|
|
2976
|
+
if node_end_dt < plan_end_dt:
|
|
2977
|
+
# if the model has an end date that has already elapsed, use that as a starting point for calculating min_intervals
|
|
2978
|
+
# instead of the plan end. If we use the plan end, we will return intervals in the future which are invalid
|
|
2979
|
+
starting_point = node_end_dt
|
|
2980
|
+
|
|
2981
|
+
snapshot_start = snapshot.node.cron_floor(starting_point)
|
|
2982
|
+
|
|
2983
|
+
for _ in range(min_intervals):
|
|
2984
|
+
# wind back the starting point by :min_intervals intervals to arrive at the minimum snapshot start date
|
|
2985
|
+
snapshot_start = snapshot.node.cron_prev(snapshot_start)
|
|
2986
|
+
|
|
2987
|
+
start_overrides[model_fqn] = min(min_child_start, snapshot_start)
|
|
2988
|
+
|
|
2989
|
+
return start_overrides
|
|
2990
|
+
|
|
2890
2991
|
def _get_max_interval_end_per_model(
|
|
2891
2992
|
self, snapshots: t.Dict[str, Snapshot], backfill_models: t.Optional[t.Set[str]]
|
|
2892
|
-
) -> t.Dict[str,
|
|
2993
|
+
) -> t.Dict[str, datetime]:
|
|
2893
2994
|
models_for_interval_end = (
|
|
2894
2995
|
self._get_models_for_interval_end(snapshots, backfill_models)
|
|
2895
2996
|
if backfill_models is not None
|
|
2896
2997
|
else None
|
|
2897
2998
|
)
|
|
2898
|
-
return
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2999
|
+
return {
|
|
3000
|
+
model_fqn: to_datetime(ts)
|
|
3001
|
+
for model_fqn, ts in self.state_sync.max_interval_end_per_model(
|
|
3002
|
+
c.PROD,
|
|
3003
|
+
models=models_for_interval_end,
|
|
3004
|
+
ensure_finalized_snapshots=self.config.plan.use_finalized_state,
|
|
3005
|
+
).items()
|
|
3006
|
+
}
|
|
2903
3007
|
|
|
2904
3008
|
@staticmethod
|
|
2905
3009
|
def _get_models_for_interval_end(
|
sqlmesh/core/node.py
CHANGED
|
@@ -31,6 +31,9 @@ class IntervalUnit(str, Enum):
|
|
|
31
31
|
IntervalUnit can be one of 5 types, YEAR, MONTH, DAY, HOUR, MINUTE. The unit is inferred
|
|
32
32
|
based on the cron schedule of a node. The minimum time delta between a sample set of dates
|
|
33
33
|
is used to determine which unit a node's schedule is.
|
|
34
|
+
|
|
35
|
+
It's designed to align with common partitioning schemes, hence why there is no WEEK unit
|
|
36
|
+
because generally tables are not partitioned by week
|
|
34
37
|
"""
|
|
35
38
|
|
|
36
39
|
YEAR = "year"
|
sqlmesh/core/plan/builder.py
CHANGED
|
@@ -5,6 +5,7 @@ import re
|
|
|
5
5
|
import typing as t
|
|
6
6
|
from collections import defaultdict
|
|
7
7
|
from functools import cached_property
|
|
8
|
+
from datetime import datetime
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
from sqlmesh.core.console import PlanBuilderConsole, get_console
|
|
@@ -85,7 +86,8 @@ class PlanBuilder:
|
|
|
85
86
|
ensure_finalized_snapshots: Whether to compare against snapshots from the latest finalized
|
|
86
87
|
environment state, or to use whatever snapshots are in the current environment state even if
|
|
87
88
|
the environment is not finalized.
|
|
88
|
-
|
|
89
|
+
start_override_per_model: A mapping of model FQNs to target start dates.
|
|
90
|
+
end_override_per_model: A mapping of model FQNs to target end dates.
|
|
89
91
|
explain: Whether to explain the plan instead of applying it.
|
|
90
92
|
"""
|
|
91
93
|
|
|
@@ -117,7 +119,8 @@ class PlanBuilder:
|
|
|
117
119
|
end_bounded: bool = False,
|
|
118
120
|
ensure_finalized_snapshots: bool = False,
|
|
119
121
|
explain: bool = False,
|
|
120
|
-
|
|
122
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
123
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
121
124
|
console: t.Optional[PlanBuilderConsole] = None,
|
|
122
125
|
user_provided_flags: t.Optional[t.Dict[str, UserProvidedFlags]] = None,
|
|
123
126
|
):
|
|
@@ -133,7 +136,8 @@ class PlanBuilder:
|
|
|
133
136
|
self._enable_preview = enable_preview
|
|
134
137
|
self._end_bounded = end_bounded
|
|
135
138
|
self._ensure_finalized_snapshots = ensure_finalized_snapshots
|
|
136
|
-
self.
|
|
139
|
+
self._start_override_per_model = start_override_per_model
|
|
140
|
+
self._end_override_per_model = end_override_per_model
|
|
137
141
|
self._environment_ttl = environment_ttl
|
|
138
142
|
self._categorizer_config = categorizer_config or CategorizerConfig()
|
|
139
143
|
self._auto_categorization_enabled = auto_categorization_enabled
|
|
@@ -280,7 +284,11 @@ class PlanBuilder:
|
|
|
280
284
|
self._adjust_new_snapshot_intervals()
|
|
281
285
|
|
|
282
286
|
deployability_index = (
|
|
283
|
-
DeployabilityIndex.create(
|
|
287
|
+
DeployabilityIndex.create(
|
|
288
|
+
self._context_diff.snapshots.values(),
|
|
289
|
+
start=self._start,
|
|
290
|
+
start_override_per_model=self._start_override_per_model,
|
|
291
|
+
)
|
|
284
292
|
if self._is_dev
|
|
285
293
|
else DeployabilityIndex.all_deployable()
|
|
286
294
|
)
|
|
@@ -291,11 +299,11 @@ class PlanBuilder:
|
|
|
291
299
|
)
|
|
292
300
|
models_to_backfill = self._build_models_to_backfill(dag, restatements)
|
|
293
301
|
|
|
294
|
-
|
|
295
|
-
if
|
|
302
|
+
end_override_per_model = self._end_override_per_model
|
|
303
|
+
if end_override_per_model and self.override_end:
|
|
296
304
|
# If the end date was provided explicitly by a user, then interval end for each individual
|
|
297
305
|
# model should be ignored.
|
|
298
|
-
|
|
306
|
+
end_override_per_model = None
|
|
299
307
|
|
|
300
308
|
# this deliberately uses the passed in self._execution_time and not self.execution_time cached property
|
|
301
309
|
# the reason is because that there can be a delay between the Plan being built and the Plan being actually run,
|
|
@@ -322,7 +330,8 @@ class PlanBuilder:
|
|
|
322
330
|
indirectly_modified=indirectly_modified,
|
|
323
331
|
deployability_index=deployability_index,
|
|
324
332
|
restatements=restatements,
|
|
325
|
-
|
|
333
|
+
start_override_per_model=self._start_override_per_model,
|
|
334
|
+
end_override_per_model=end_override_per_model,
|
|
326
335
|
selected_models_to_backfill=self._backfill_models,
|
|
327
336
|
models_to_backfill=models_to_backfill,
|
|
328
337
|
effective_from=self._effective_from,
|
sqlmesh/core/plan/definition.py
CHANGED
|
@@ -57,7 +57,8 @@ class Plan(PydanticModel, frozen=True):
|
|
|
57
57
|
|
|
58
58
|
deployability_index: DeployabilityIndex
|
|
59
59
|
restatements: t.Dict[SnapshotId, Interval]
|
|
60
|
-
|
|
60
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]]
|
|
61
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]]
|
|
61
62
|
|
|
62
63
|
selected_models_to_backfill: t.Optional[t.Set[str]] = None
|
|
63
64
|
"""Models that have been explicitly selected for backfill by a user."""
|
|
@@ -177,7 +178,8 @@ class Plan(PydanticModel, frozen=True):
|
|
|
177
178
|
execution_time=self.execution_time,
|
|
178
179
|
restatements=self.restatements,
|
|
179
180
|
deployability_index=self.deployability_index,
|
|
180
|
-
|
|
181
|
+
start_override_per_model=self.start_override_per_model,
|
|
182
|
+
end_override_per_model=self.end_override_per_model,
|
|
181
183
|
end_bounded=self.end_bounded,
|
|
182
184
|
).items()
|
|
183
185
|
if snapshot.is_model and missing
|
|
@@ -265,7 +267,8 @@ class Plan(PydanticModel, frozen=True):
|
|
|
265
267
|
removed_snapshots=sorted(self.context_diff.removed_snapshots),
|
|
266
268
|
requires_backfill=self.requires_backfill,
|
|
267
269
|
models_to_backfill=self.models_to_backfill,
|
|
268
|
-
|
|
270
|
+
start_override_per_model=self.start_override_per_model,
|
|
271
|
+
end_override_per_model=self.end_override_per_model,
|
|
269
272
|
execution_time=self.execution_time,
|
|
270
273
|
disabled_restatement_models={
|
|
271
274
|
s.name
|
|
@@ -303,7 +306,8 @@ class EvaluatablePlan(PydanticModel):
|
|
|
303
306
|
removed_snapshots: t.List[SnapshotId]
|
|
304
307
|
requires_backfill: bool
|
|
305
308
|
models_to_backfill: t.Optional[t.Set[str]] = None
|
|
306
|
-
|
|
309
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None
|
|
310
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None
|
|
307
311
|
execution_time: t.Optional[TimeLike] = None
|
|
308
312
|
disabled_restatement_models: t.Set[str]
|
|
309
313
|
environment_statements: t.Optional[t.List[EnvironmentStatements]] = None
|
sqlmesh/core/plan/evaluator.py
CHANGED
|
@@ -256,7 +256,8 @@ class BuiltInPlanEvaluator(PlanEvaluator):
|
|
|
256
256
|
plan.end,
|
|
257
257
|
execution_time=plan.execution_time,
|
|
258
258
|
end_bounded=plan.end_bounded,
|
|
259
|
-
|
|
259
|
+
start_override_per_model=plan.start_override_per_model,
|
|
260
|
+
end_override_per_model=plan.end_override_per_model,
|
|
260
261
|
)
|
|
261
262
|
|
|
262
263
|
if completion_status.is_failure:
|
sqlmesh/core/plan/stages.py
CHANGED
|
@@ -524,7 +524,8 @@ class PlanStagesBuilder:
|
|
|
524
524
|
},
|
|
525
525
|
deployability_index=deployability_index,
|
|
526
526
|
end_bounded=plan.end_bounded,
|
|
527
|
-
|
|
527
|
+
start_override_per_model=plan.start_override_per_model,
|
|
528
|
+
end_override_per_model=plan.end_override_per_model,
|
|
528
529
|
)
|
|
529
530
|
|
|
530
531
|
def _get_audit_only_snapshots(
|
sqlmesh/core/scheduler.py
CHANGED
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
import logging
|
|
3
3
|
import typing as t
|
|
4
4
|
import time
|
|
5
|
+
from datetime import datetime
|
|
5
6
|
from sqlglot import exp
|
|
6
7
|
from sqlmesh.core import constants as c
|
|
7
8
|
from sqlmesh.core.console import Console, get_console
|
|
@@ -105,7 +106,8 @@ class Scheduler:
|
|
|
105
106
|
execution_time: t.Optional[TimeLike] = None,
|
|
106
107
|
deployability_index: t.Optional[DeployabilityIndex] = None,
|
|
107
108
|
restatements: t.Optional[t.Dict[SnapshotId, Interval]] = None,
|
|
108
|
-
|
|
109
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
110
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
109
111
|
ignore_cron: bool = False,
|
|
110
112
|
end_bounded: bool = False,
|
|
111
113
|
selected_snapshots: t.Optional[t.Set[str]] = None,
|
|
@@ -123,7 +125,8 @@ class Scheduler:
|
|
|
123
125
|
execution_time: The date/time reference to use for execution time. Defaults to now.
|
|
124
126
|
deployability_index: Determines snapshots that are deployable in the context of this evaluation.
|
|
125
127
|
restatements: A set of snapshot names being restated.
|
|
126
|
-
|
|
128
|
+
start_override_per_model: A mapping of model FQNs to target start dates.
|
|
129
|
+
end_override_per_model: A mapping of model FQNs to target end dates.
|
|
127
130
|
ignore_cron: Whether to ignore the node's cron schedule.
|
|
128
131
|
end_bounded: If set to true, the returned intervals will be bounded by the target end date, disregarding lookback,
|
|
129
132
|
allow_partials, and other attributes that could cause the intervals to exceed the target end date.
|
|
@@ -136,7 +139,8 @@ class Scheduler:
|
|
|
136
139
|
execution_time=execution_time,
|
|
137
140
|
deployability_index=deployability_index,
|
|
138
141
|
restatements=restatements,
|
|
139
|
-
|
|
142
|
+
start_override_per_model=start_override_per_model,
|
|
143
|
+
end_override_per_model=end_override_per_model,
|
|
140
144
|
ignore_cron=ignore_cron,
|
|
141
145
|
end_bounded=end_bounded,
|
|
142
146
|
)
|
|
@@ -212,7 +216,8 @@ class Scheduler:
|
|
|
212
216
|
end: t.Optional[TimeLike] = None,
|
|
213
217
|
execution_time: t.Optional[TimeLike] = None,
|
|
214
218
|
restatements: t.Optional[t.Dict[SnapshotId, Interval]] = None,
|
|
215
|
-
|
|
219
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
220
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
216
221
|
ignore_cron: bool = False,
|
|
217
222
|
end_bounded: bool = False,
|
|
218
223
|
selected_snapshots: t.Optional[t.Set[str]] = None,
|
|
@@ -227,7 +232,8 @@ class Scheduler:
|
|
|
227
232
|
end=end,
|
|
228
233
|
execution_time=execution_time,
|
|
229
234
|
remove_intervals=restatements,
|
|
230
|
-
|
|
235
|
+
start_override_per_model=start_override_per_model,
|
|
236
|
+
end_override_per_model=end_override_per_model,
|
|
231
237
|
ignore_cron=ignore_cron,
|
|
232
238
|
end_bounded=end_bounded,
|
|
233
239
|
selected_snapshots=selected_snapshots,
|
|
@@ -243,7 +249,8 @@ class Scheduler:
|
|
|
243
249
|
start: TimeLike,
|
|
244
250
|
end: TimeLike,
|
|
245
251
|
execution_time: t.Optional[TimeLike] = None,
|
|
246
|
-
|
|
252
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
253
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
247
254
|
ignore_cron: bool = False,
|
|
248
255
|
end_bounded: bool = False,
|
|
249
256
|
selected_snapshots: t.Optional[t.Set[str]] = None,
|
|
@@ -266,7 +273,8 @@ class Scheduler:
|
|
|
266
273
|
end=end,
|
|
267
274
|
execution_time=execution_time,
|
|
268
275
|
remove_intervals=remove_intervals,
|
|
269
|
-
|
|
276
|
+
start_override_per_model=start_override_per_model,
|
|
277
|
+
end_override_per_model=end_override_per_model,
|
|
270
278
|
ignore_cron=ignore_cron,
|
|
271
279
|
end_bounded=end_bounded,
|
|
272
280
|
selected_snapshots=selected_snapshots,
|
|
@@ -565,7 +573,8 @@ class Scheduler:
|
|
|
565
573
|
end: t.Optional[TimeLike] = None,
|
|
566
574
|
execution_time: t.Optional[TimeLike] = None,
|
|
567
575
|
remove_intervals: t.Optional[t.Dict[SnapshotId, Interval]] = None,
|
|
568
|
-
|
|
576
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
577
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
569
578
|
ignore_cron: bool = False,
|
|
570
579
|
end_bounded: bool = False,
|
|
571
580
|
selected_snapshots: t.Optional[t.Set[str]] = None,
|
|
@@ -586,7 +595,8 @@ class Scheduler:
|
|
|
586
595
|
execution_time: The date/time time reference to use for execution time. Defaults to now.
|
|
587
596
|
remove_intervals: A dict of snapshots to their intervals. For evaluation, these are the intervals that will be restated. For audits,
|
|
588
597
|
these are the intervals that will be reaudited
|
|
589
|
-
|
|
598
|
+
start_override_per_model: A mapping of model FQNs to target start dates.
|
|
599
|
+
end_override_per_model: A mapping of model FQNs to target end dates.
|
|
590
600
|
ignore_cron: Whether to ignore the node's cron schedule.
|
|
591
601
|
end_bounded: If set to true, the evaluated intervals will be bounded by the target end date, disregarding lookback,
|
|
592
602
|
allow_partials, and other attributes that could cause the intervals to exceed the target end date.
|
|
@@ -634,7 +644,8 @@ class Scheduler:
|
|
|
634
644
|
execution_time,
|
|
635
645
|
deployability_index=deployability_index,
|
|
636
646
|
restatements=remove_intervals,
|
|
637
|
-
|
|
647
|
+
start_override_per_model=start_override_per_model,
|
|
648
|
+
end_override_per_model=end_override_per_model,
|
|
638
649
|
ignore_cron=ignore_cron,
|
|
639
650
|
end_bounded=end_bounded,
|
|
640
651
|
selected_snapshots=selected_snapshots,
|
|
@@ -797,7 +808,8 @@ def merged_missing_intervals(
|
|
|
797
808
|
execution_time: t.Optional[TimeLike] = None,
|
|
798
809
|
deployability_index: t.Optional[DeployabilityIndex] = None,
|
|
799
810
|
restatements: t.Optional[t.Dict[SnapshotId, Interval]] = None,
|
|
800
|
-
|
|
811
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
812
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
801
813
|
ignore_cron: bool = False,
|
|
802
814
|
end_bounded: bool = False,
|
|
803
815
|
) -> SnapshotToIntervals:
|
|
@@ -815,7 +827,8 @@ def merged_missing_intervals(
|
|
|
815
827
|
execution_time: The date/time reference to use for execution time. Defaults to now.
|
|
816
828
|
deployability_index: Determines snapshots that are deployable in the context of this evaluation.
|
|
817
829
|
restatements: A set of snapshot names being restated.
|
|
818
|
-
|
|
830
|
+
start_override_per_model: A mapping of model FQNs to target start dates.
|
|
831
|
+
end_override_per_model: A mapping of model FQNs to target end dates.
|
|
819
832
|
ignore_cron: Whether to ignore the node's cron schedule.
|
|
820
833
|
end_bounded: If set to true, the returned intervals will be bounded by the target end date, disregarding lookback,
|
|
821
834
|
allow_partials, and other attributes that could cause the intervals to exceed the target end date.
|
|
@@ -830,7 +843,8 @@ def merged_missing_intervals(
|
|
|
830
843
|
deployability_index=deployability_index,
|
|
831
844
|
execution_time=execution_time or now_timestamp(),
|
|
832
845
|
restatements=restatements,
|
|
833
|
-
|
|
846
|
+
start_override_per_model=start_override_per_model,
|
|
847
|
+
end_override_per_model=end_override_per_model,
|
|
834
848
|
ignore_cron=ignore_cron,
|
|
835
849
|
end_bounded=end_bounded,
|
|
836
850
|
)
|
|
@@ -844,7 +858,8 @@ def compute_interval_params(
|
|
|
844
858
|
deployability_index: t.Optional[DeployabilityIndex] = None,
|
|
845
859
|
execution_time: t.Optional[TimeLike] = None,
|
|
846
860
|
restatements: t.Optional[t.Dict[SnapshotId, Interval]] = None,
|
|
847
|
-
|
|
861
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
862
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
848
863
|
ignore_cron: bool = False,
|
|
849
864
|
end_bounded: bool = False,
|
|
850
865
|
) -> SnapshotToIntervals:
|
|
@@ -862,7 +877,8 @@ def compute_interval_params(
|
|
|
862
877
|
deployability_index: Determines snapshots that are deployable in the context of this evaluation.
|
|
863
878
|
execution_time: The date/time reference to use for execution time.
|
|
864
879
|
restatements: A dict of snapshot names being restated and their intervals.
|
|
865
|
-
|
|
880
|
+
start_override_per_model: A mapping of model FQNs to target start dates.
|
|
881
|
+
end_override_per_model: A mapping of model FQNs to target end dates.
|
|
866
882
|
ignore_cron: Whether to ignore the node's cron schedule.
|
|
867
883
|
end_bounded: If set to true, the returned intervals will be bounded by the target end date, disregarding lookback,
|
|
868
884
|
allow_partials, and other attributes that could cause the intervals to exceed the target end date.
|
|
@@ -879,7 +895,8 @@ def compute_interval_params(
|
|
|
879
895
|
execution_time=execution_time,
|
|
880
896
|
restatements=restatements,
|
|
881
897
|
deployability_index=deployability_index,
|
|
882
|
-
|
|
898
|
+
start_override_per_model=start_override_per_model,
|
|
899
|
+
end_override_per_model=end_override_per_model,
|
|
883
900
|
ignore_cron=ignore_cron,
|
|
884
901
|
end_bounded=end_bounded,
|
|
885
902
|
).items():
|
|
@@ -1469,7 +1469,8 @@ class DeployabilityIndex(PydanticModel, frozen=True):
|
|
|
1469
1469
|
def create(
|
|
1470
1470
|
cls,
|
|
1471
1471
|
snapshots: t.Dict[SnapshotId, Snapshot] | t.Collection[Snapshot],
|
|
1472
|
-
start: t.Optional[TimeLike] = None,
|
|
1472
|
+
start: t.Optional[TimeLike] = None, # plan start
|
|
1473
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
1473
1474
|
) -> DeployabilityIndex:
|
|
1474
1475
|
if not isinstance(snapshots, dict):
|
|
1475
1476
|
snapshots = {s.snapshot_id: s for s in snapshots}
|
|
@@ -1477,6 +1478,7 @@ class DeployabilityIndex(PydanticModel, frozen=True):
|
|
|
1477
1478
|
deployability_mapping: t.Dict[SnapshotId, bool] = {}
|
|
1478
1479
|
children_deployability_mapping: t.Dict[SnapshotId, bool] = {}
|
|
1479
1480
|
representative_shared_version_ids: t.Set[SnapshotId] = set()
|
|
1481
|
+
start_override_per_model = start_override_per_model or {}
|
|
1480
1482
|
|
|
1481
1483
|
start_date_cache: t.Optional[t.Dict[str, datetime]] = {}
|
|
1482
1484
|
|
|
@@ -1499,12 +1501,12 @@ class DeployabilityIndex(PydanticModel, frozen=True):
|
|
|
1499
1501
|
snapshot.is_model and snapshot.model.auto_restatement_cron is not None
|
|
1500
1502
|
)
|
|
1501
1503
|
|
|
1504
|
+
snapshot_start = start_override_per_model.get(
|
|
1505
|
+
node.name, start_date(snapshot, snapshots.values(), cache=start_date_cache)
|
|
1506
|
+
)
|
|
1507
|
+
|
|
1502
1508
|
is_valid_start = (
|
|
1503
|
-
snapshot.is_valid_start(
|
|
1504
|
-
start, start_date(snapshot, snapshots.values(), start_date_cache)
|
|
1505
|
-
)
|
|
1506
|
-
if start is not None
|
|
1507
|
-
else True
|
|
1509
|
+
snapshot.is_valid_start(start, snapshot_start) if start is not None else True
|
|
1508
1510
|
)
|
|
1509
1511
|
|
|
1510
1512
|
if (
|
|
@@ -1800,7 +1802,8 @@ def missing_intervals(
|
|
|
1800
1802
|
execution_time: t.Optional[TimeLike] = None,
|
|
1801
1803
|
restatements: t.Optional[t.Dict[SnapshotId, Interval]] = None,
|
|
1802
1804
|
deployability_index: t.Optional[DeployabilityIndex] = None,
|
|
1803
|
-
|
|
1805
|
+
start_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
1806
|
+
end_override_per_model: t.Optional[t.Dict[str, datetime]] = None,
|
|
1804
1807
|
ignore_cron: bool = False,
|
|
1805
1808
|
end_bounded: bool = False,
|
|
1806
1809
|
) -> t.Dict[Snapshot, Intervals]:
|
|
@@ -1817,13 +1820,15 @@ def missing_intervals(
|
|
|
1817
1820
|
else earliest_start_date(snapshots, cache=cache, relative_to=end_date)
|
|
1818
1821
|
)
|
|
1819
1822
|
restatements = restatements or {}
|
|
1820
|
-
|
|
1823
|
+
start_override_per_model = start_override_per_model or {}
|
|
1824
|
+
end_override_per_model = end_override_per_model or {}
|
|
1821
1825
|
deployability_index = deployability_index or DeployabilityIndex.all_deployable()
|
|
1822
1826
|
|
|
1823
1827
|
for snapshot in snapshots.values():
|
|
1824
1828
|
if not snapshot.evaluatable:
|
|
1825
1829
|
continue
|
|
1826
|
-
|
|
1830
|
+
|
|
1831
|
+
snapshot_start_date = start_override_per_model.get(snapshot.name, start_dt)
|
|
1827
1832
|
snapshot_end_date: TimeLike = end_date
|
|
1828
1833
|
|
|
1829
1834
|
restated_interval = restatements.get(snapshot.snapshot_id)
|
|
@@ -1833,9 +1838,9 @@ def missing_intervals(
|
|
|
1833
1838
|
snapshot.intervals = snapshot.intervals.copy()
|
|
1834
1839
|
snapshot.remove_interval(restated_interval)
|
|
1835
1840
|
|
|
1836
|
-
existing_interval_end =
|
|
1841
|
+
existing_interval_end = end_override_per_model.get(snapshot.name)
|
|
1837
1842
|
if existing_interval_end:
|
|
1838
|
-
if
|
|
1843
|
+
if snapshot_start_date >= existing_interval_end:
|
|
1839
1844
|
# The start exceeds the provided interval end, so we can skip this snapshot
|
|
1840
1845
|
# since it doesn't have missing intervals by definition
|
|
1841
1846
|
continue
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
sqlmesh/__init__.py,sha256=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
|
|
2
|
-
sqlmesh/_version.py,sha256=
|
|
2
|
+
sqlmesh/_version.py,sha256=8TEWJVO9dASKRsPIXBTYMc8BKwc4f8TClP6jWf6SAkE,530
|
|
3
3
|
sqlmesh/magics.py,sha256=R9U0Mp9ZQhDYe751nxAQDLaMv3zLAR4HcTdIflKTmEE,41709
|
|
4
4
|
sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
sqlmesh/cicd/bot.py,sha256=2zlbn-DXkqQzr3lA0__IGU4XaIfXBXBKLWXNI2DRJX8,759
|
|
7
7
|
sqlmesh/cicd/config.py,sha256=mpgkisSBBovlNrNZir2unT8Wes6b38RW2UsU_o4e8vY,109
|
|
8
8
|
sqlmesh/cli/__init__.py,sha256=MAXAyO7isbyM-PaSdFjkJNcjn32WjOl0XzxT5gvp_vo,1690
|
|
9
|
-
sqlmesh/cli/main.py,sha256=
|
|
9
|
+
sqlmesh/cli/main.py,sha256=vzQmFtz80_nVPJKYzFVw9ea5f-fM41Ux4-qI4GeI0_w,36053
|
|
10
10
|
sqlmesh/cli/options.py,sha256=-4ZclMIeIg8tghLowtmQNmpEFlm0QtOVEh40NqRdFHA,2499
|
|
11
11
|
sqlmesh/cli/project_init.py,sha256=5JmDmUK0WJs39hM-p76uzHYdo1Hnx6fKuJg_pR3Hn5A,16419
|
|
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=
|
|
14
|
+
sqlmesh/core/console.py,sha256=ObpdArJOXDOihWPXsWIUuwiQ64cMlroNWJHqQPkVqC0,160753
|
|
15
15
|
sqlmesh/core/constants.py,sha256=gUABXWYgH_XOSbaZAJsR5o1dmA61JDCvBDyxqqXX3LM,2630
|
|
16
|
-
sqlmesh/core/context.py,sha256=
|
|
16
|
+
sqlmesh/core/context.py,sha256=VO2Sp0u3CRmUoQI0z2Qwfzp4bhqKdtxlG0az1tND2_w,124223
|
|
17
17
|
sqlmesh/core/context_diff.py,sha256=CeUmMBJzN__98YohrtAiIYPIZI9mrGBk6bVADWBLUw8,21692
|
|
18
18
|
sqlmesh/core/dialect.py,sha256=1ykYwb9WZn_nCaX08PcQ0BJh2Pihv9SPvoMNjpMeCfs,50158
|
|
19
19
|
sqlmesh/core/environment.py,sha256=7DbJX0r5nZRU3LhcgIxbSV-JosQYDjAt3V5Wc2Fpns8,13005
|
|
20
20
|
sqlmesh/core/lineage.py,sha256=zjB0Zfamo2Fja2r5SSZPMbrEKTXr1WjozZPVqvxdybI,3143
|
|
21
21
|
sqlmesh/core/loader.py,sha256=Imb65SX5TtvQrtlilin2hkYg12gm9e9c30I8o95nkVE,40534
|
|
22
22
|
sqlmesh/core/macros.py,sha256=Me4QjgW_K4DzQVi8I3G0XwoC3cXSFFWt3sJyynZ2GOM,60585
|
|
23
|
-
sqlmesh/core/node.py,sha256=
|
|
23
|
+
sqlmesh/core/node.py,sha256=9V2zLRRODgondxQdB6jA5wVH0KCYon70gre0LFBgrM8,14648
|
|
24
24
|
sqlmesh/core/notification_target.py,sha256=PPGoDrgbRKxr27vJEu03XqNTQLYTw0ZF_b0yAapxGeI,16158
|
|
25
25
|
sqlmesh/core/reference.py,sha256=k7OSkLqTjPR8WJjNeFj0xAJ297nZUMgb_iTVwKRRKjc,4875
|
|
26
26
|
sqlmesh/core/renderer.py,sha256=ksdD2x2Q5Ns5fOLIGfWIznx_T3fXbP3CfwUhD5kVSOQ,26674
|
|
27
|
-
sqlmesh/core/scheduler.py,sha256=
|
|
27
|
+
sqlmesh/core/scheduler.py,sha256=5qSC-EHKotWpwFFvnwDHw3feYfz9c8_9gBGRfdeu8P4,40512
|
|
28
28
|
sqlmesh/core/schema_diff.py,sha256=Sp2MoqAngp-yTYevkLaf9jb26SuAdGXoZ54g5MjWowU,30516
|
|
29
29
|
sqlmesh/core/schema_loader.py,sha256=lvrI9k7hr1P4X4E6t3U-KrcuvdQuw0UdNlN90P2s52w,3563
|
|
30
30
|
sqlmesh/core/selector.py,sha256=CBuCbaFzidinaoS66o4MY9F-1C3k9YddNMyUv-5Z2i8,12815
|
|
@@ -94,15 +94,15 @@ sqlmesh/core/model/meta.py,sha256=D9InI9M2-IXeb34vkXNQSLALL8xVXjZ_LXwI-Tqxm7I,21
|
|
|
94
94
|
sqlmesh/core/model/schema.py,sha256=_HMYfzK9wWXh7_CQDIIGnuQUD4aiX3o5D2cRp2sERzc,3387
|
|
95
95
|
sqlmesh/core/model/seed.py,sha256=a0M-1zY1gOkN5ph2GQyataEdBSCtq50YjeFk2LyvInI,5058
|
|
96
96
|
sqlmesh/core/plan/__init__.py,sha256=NKSvM7ZBVjw9ho3J65M1wFvG3KURB8PJ0FHHLmtSF44,443
|
|
97
|
-
sqlmesh/core/plan/builder.py,sha256=
|
|
98
|
-
sqlmesh/core/plan/definition.py,sha256=
|
|
99
|
-
sqlmesh/core/plan/evaluator.py,sha256=
|
|
97
|
+
sqlmesh/core/plan/builder.py,sha256=TQVSGiGbQi9tro0tBlcL2f5BEvyOYNiLuB3yz8PRUzA,41859
|
|
98
|
+
sqlmesh/core/plan/definition.py,sha256=yrX_uZMXi29ltkuowWhNUOi1kd0Uq0TQoM574EI6JHo,14019
|
|
99
|
+
sqlmesh/core/plan/evaluator.py,sha256=FNA4oQ29lZsabKZU36T2wu7QQymwAfCu6zhirdPKuCg,20627
|
|
100
100
|
sqlmesh/core/plan/explainer.py,sha256=aBkvtM9eog_2NIglazSDdG_i9TTCdFSVOkCw5N8O-1k,12028
|
|
101
|
-
sqlmesh/core/plan/stages.py,sha256=
|
|
101
|
+
sqlmesh/core/plan/stages.py,sha256=7iiVZLSRoI1kSEMyOuuW6gvUA-eyALUfdW5vDh_N4jU,22040
|
|
102
102
|
sqlmesh/core/snapshot/__init__.py,sha256=Z5HTetNCZGoKF1WAKXk4LWL9dc8EC8lwS2O4TtoBmt4,1317
|
|
103
103
|
sqlmesh/core/snapshot/cache.py,sha256=bgqCR2hyf6r2A_8QP1EnXFK25gDX37-Zg0YeMuETWxg,3934
|
|
104
104
|
sqlmesh/core/snapshot/categorizer.py,sha256=qGG5870mu1jR2whKisSBH_GFbsyh96RnzJDgkN7DV9g,2482
|
|
105
|
-
sqlmesh/core/snapshot/definition.py,sha256=
|
|
105
|
+
sqlmesh/core/snapshot/definition.py,sha256=JBrvHx9ZPVWxY649IOXOYs4RKPzgLYvfdxXsdCewad0,85738
|
|
106
106
|
sqlmesh/core/snapshot/evaluator.py,sha256=3mjrSp9ggd9uKhuZURrY0HtuCc_WAPsH4PYvQlqmn9o,90443
|
|
107
107
|
sqlmesh/core/state_sync/__init__.py,sha256=B60xj-_Xk-4jas3UphLvwkuf04G-9AyGckcblXE0aRg,869
|
|
108
108
|
sqlmesh/core/state_sync/base.py,sha256=AdqWmbhnvRFqVcFK6L01uCvpBVAYGuMrm4P0D3u_NaU,18334
|
|
@@ -284,7 +284,7 @@ sqlmesh/utils/pydantic.py,sha256=o_NsXbIpDqNpUA1Uc5xF0ZzoXQYYB0DfHwdRxBwXPNk,120
|
|
|
284
284
|
sqlmesh/utils/rich.py,sha256=BpB47G0-JcU41LkGkeGKroexj4NOV5fox4-GOIXPgIc,3545
|
|
285
285
|
sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
|
|
286
286
|
sqlmesh/utils/yaml.py,sha256=hvo5lmybYLcIx4p6CQwufS8X4MbwS60lEBnCmYJCXmU,2336
|
|
287
|
-
sqlmesh-0.199.1.
|
|
287
|
+
sqlmesh-0.199.1.dev19.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
|
|
288
288
|
web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
289
289
|
web/client/dist/index.html,sha256=DAv6ABGogw4xRLb0T_92WP_S7XWyqVhwBgGKWtuQwU4,5472
|
|
290
290
|
web/client/dist/assets/Audits-BuHAmFO8.js,sha256=zbYUF6WdUGMbnMm01GMNPb7xAJwj-o5wMdL56vPo2qE,1041
|
|
@@ -402,8 +402,8 @@ web/server/api/endpoints/models.py,sha256=ud-lRwriyI_OYg9tZchrBgeiXELiRTLNEodraf
|
|
|
402
402
|
web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
|
|
403
403
|
web/server/api/endpoints/plan.py,sha256=bbbY50W_2MsZSTxOHWMKz0tbIm75nsRSlPy8GI2fg9Q,9306
|
|
404
404
|
web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
|
|
405
|
-
sqlmesh-0.199.1.
|
|
406
|
-
sqlmesh-0.199.1.
|
|
407
|
-
sqlmesh-0.199.1.
|
|
408
|
-
sqlmesh-0.199.1.
|
|
409
|
-
sqlmesh-0.199.1.
|
|
405
|
+
sqlmesh-0.199.1.dev19.dist-info/METADATA,sha256=rBj57KhTPJ8EL5R4NF3jtAeY73CnajeEUNzzQc0viiQ,26659
|
|
406
|
+
sqlmesh-0.199.1.dev19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
407
|
+
sqlmesh-0.199.1.dev19.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
|
|
408
|
+
sqlmesh-0.199.1.dev19.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
|
|
409
|
+
sqlmesh-0.199.1.dev19.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|