Skip to content

Commit 2d30d7f

Browse files
authored
make startdate relative so that development is faster (#638)
1 parent 1abc74d commit 2d30d7f

File tree

9 files changed

+91
-40
lines changed

9 files changed

+91
-40
lines changed

examples/sushi/models/items.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
@model(
5151
"sushi.items",
5252
kind=IncrementalByTimeRangeKind(time_column="ds"),
53-
start="Jan 1 2022",
53+
start="3 months ago",
5454
cron="@daily",
5555
batch_size=30,
5656
columns={

examples/sushi/models/orders.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"sushi.orders",
1818
description="Table of sushi orders.",
1919
kind=IncrementalByTimeRangeKind(time_column="ds"),
20-
start="2022-01-01",
20+
start="3 months ago",
2121
cron="@daily",
2222
batch_size=30,
2323
columns={

sqlmesh/core/snapshot/definition.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ def _model_metadata_hash(model: Model, audits: t.Dict[str, Audit]) -> str:
768768
model.dialect,
769769
model.owner,
770770
model.description,
771-
str(to_timestamp(model.start)) if model.start else None,
771+
str(model.start) if model.start else None,
772772
str(model.batch_size) if model.batch_size is not None else None,
773773
]
774774

sqlmesh/core/state_sync/common.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ def unpause_snapshots(
218218
def _ensure_no_gaps(
219219
self, target_snapshots: t.Iterable[Snapshot], target_environment: Environment
220220
) -> None:
221+
from sqlmesh.core.scheduler import start_date
222+
221223
target_snapshots_by_name = {s.name: s for s in target_snapshots}
222224

223225
changed_version_prev_snapshots_by_name = {
@@ -257,7 +259,8 @@ def _ensure_no_gaps(
257259
and prev_snapshot.intervals
258260
):
259261
missing_intervals = target_snapshot.missing_intervals(
260-
prev_snapshot.intervals[0][0],
262+
start_date(target_snapshot, target_snapshots_by_name.values())
263+
or prev_snapshot.intervals[0][0],
261264
prev_snapshot.intervals[-1][1],
262265
)
263266
if missing_intervals:

tests/conftest.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,36 @@ def duck_conn() -> duckdb.DuckDBPyConnection:
2727
return duckdb.connect()
2828

2929

30+
def push_plan(context: Context, plan: Plan) -> None:
31+
plan_evaluator = BuiltInPlanEvaluator(context.state_sync, context.snapshot_evaluator)
32+
plan_evaluator._push(plan)
33+
plan_evaluator._promote(plan)
34+
35+
3036
@pytest.fixture()
3137
def sushi_context_pre_scheduling(mocker: MockerFixture) -> Context:
3238
context, plan = init_and_plan_sushi_context("examples/sushi", mocker)
39+
push_plan(context, plan)
40+
return context
3341

34-
plan_evaluator = BuiltInPlanEvaluator(context.state_sync, context.snapshot_evaluator)
35-
plan_evaluator._push(plan)
36-
plan_evaluator._promote(plan)
3742

43+
@pytest.fixture()
44+
def sushi_context_fixed_date(mocker: MockerFixture) -> Context:
45+
context, plan = init_and_plan_sushi_context("examples/sushi", mocker)
46+
47+
for model in context.models.values():
48+
if model.start:
49+
context.upsert_model(model.name, start="2022-01-01")
50+
51+
plan = context.plan("prod")
52+
plan.set_start("1 week ago")
53+
push_plan(context, plan)
3854
return context
3955

4056

4157
@pytest.fixture()
4258
def sushi_context(mocker: MockerFixture) -> Context:
4359
context, plan = init_and_plan_sushi_context("examples/sushi", mocker)
44-
4560
context.apply(plan)
4661
return context
4762

@@ -71,10 +86,6 @@ def init_and_plan_sushi_context(
7186
path: str, mocker: MockerFixture, start: TimeLike = "1 week ago"
7287
) -> t.Tuple[Context, Plan]:
7388
sushi_context = Context(path=path, config="test_config")
74-
75-
for snapshot in sushi_context.snapshots.values():
76-
snapshot.set_version()
77-
7889
confirm = mocker.patch("sqlmesh.core.console.Confirm")
7990
confirm.ask.return_value = False
8091

tests/core/test_context.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from sqlmesh.core.dialect import parse
1212
from sqlmesh.core.model import load_model
1313
from sqlmesh.core.plan import BuiltInPlanEvaluator, Plan
14+
from sqlmesh.utils.date import yesterday_ds
1415
from sqlmesh.utils.errors import ConfigError
1516
from tests.utils.test_filesystem import create_temp_file
1617

@@ -217,7 +218,8 @@ def test_render(sushi_context, assert_exp_eq):
217218
def test_diff(sushi_context: Context, mocker: MockerFixture):
218219
mock_console = mocker.Mock()
219220
sushi_context.console = mock_console
220-
sushi_context.run(start="2022-01-01", end="2022-01-01", latest="2022-01-01")
221+
yesterday = yesterday_ds()
222+
sushi_context.run(start=yesterday, end=yesterday, latest=yesterday)
221223

222224
plan_evaluator = BuiltInPlanEvaluator(
223225
sushi_context.state_sync, sushi_context.snapshot_evaluator
@@ -324,8 +326,8 @@ def test():
324326
def test_plan_apply(sushi_context) -> None:
325327
plan = sushi_context.plan(
326328
"dev",
327-
start="2022-01-01",
328-
end="2022-01-01",
329+
start=yesterday_ds(),
330+
end=yesterday_ds(),
329331
)
330332
sushi_context.apply(plan)
331333
assert sushi_context.state_reader.get_environment("dev")

tests/core/test_scheduler.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,17 @@
99

1010

1111
@pytest.fixture
12-
def scheduler(sushi_context_pre_scheduling: Context) -> Scheduler:
13-
return sushi_context_pre_scheduling.scheduler()
12+
def scheduler(sushi_context_fixed_date: Context) -> Scheduler:
13+
return sushi_context_fixed_date.scheduler()
1414

1515

1616
@pytest.fixture
17-
def orders(sushi_context_pre_scheduling: Context) -> Snapshot:
18-
return sushi_context_pre_scheduling.snapshots["sushi.orders"]
17+
def orders(sushi_context_fixed_date: Context) -> Snapshot:
18+
return sushi_context_fixed_date.snapshots["sushi.orders"]
1919

2020

21-
def test_interval_params(
22-
scheduler: Scheduler, sushi_context_pre_scheduling: Context, orders: Snapshot
23-
):
24-
waiter_revenue = sushi_context_pre_scheduling.snapshots["sushi.waiter_revenue_by_day"]
21+
def test_interval_params(scheduler: Scheduler, sushi_context_fixed_date: Context, orders: Snapshot):
22+
waiter_revenue = sushi_context_fixed_date.snapshots["sushi.waiter_revenue_by_day"]
2523
start_ds = "2022-01-01"
2624
end_ds = "2022-02-05"
2725
assert scheduler._interval_params([orders, waiter_revenue], start_ds, end_ds) == {
@@ -53,8 +51,8 @@ def test_interval_params_nonconsecutive(scheduler: Scheduler, orders: Snapshot):
5351
}
5452

5553

56-
def test_interval_params_missing(scheduler: Scheduler, sushi_context_pre_scheduling: Context):
57-
waiters = sushi_context_pre_scheduling.snapshots["sushi.waiter_as_customer_by_day"]
54+
def test_interval_params_missing(scheduler: Scheduler, sushi_context_fixed_date: Context):
55+
waiters = sushi_context_fixed_date.snapshots["sushi.waiter_as_customer_by_day"]
5856

5957
start_ds = "2022-01-01"
6058
end_ds = "2022-03-01"
@@ -66,34 +64,34 @@ def test_interval_params_missing(scheduler: Scheduler, sushi_context_pre_schedul
6664

6765

6866
def test_multi_version_snapshots(
69-
sushi_context_pre_scheduling: Context, scheduler: Scheduler, make_snapshot
67+
sushi_context_fixed_date: Context, scheduler: Scheduler, make_snapshot
7068
):
7169
start_ds = "2022-01-01"
7270
end_ds = "2022-02-05"
7371

74-
model = sushi_context_pre_scheduling.models["sushi.waiter_as_customer_by_day"]
72+
model = sushi_context_fixed_date.models["sushi.waiter_as_customer_by_day"]
7573

7674
items_a = make_snapshot(
7775
model,
78-
models=sushi_context_pre_scheduling.models,
76+
models=sushi_context_fixed_date.models,
7977
version="1",
8078
)
8179
items_a.fingerprint = SnapshotFingerprint(data_hash="data", metadata_hash="metadata")
8280
items_a.add_interval("2022-01-10", "2022-01-15")
83-
sushi_context_pre_scheduling.state_sync.push_snapshots([items_a])
81+
sushi_context_fixed_date.state_sync.push_snapshots([items_a])
8482

85-
model = sushi_context_pre_scheduling.upsert_model(
83+
model = sushi_context_fixed_date.upsert_model(
8684
model,
8785
query=parse_one("SELECT 1::INT, '2022-01-01'::TEXT AS ds"),
8886
)
8987

9088
items_b = make_snapshot(
9189
model,
92-
models=sushi_context_pre_scheduling.models,
90+
models=sushi_context_fixed_date.models,
9391
version="1",
9492
)
9593
items_b.add_interval("2022-01-20", "2022-01-25")
96-
sushi_context_pre_scheduling.state_sync.push_snapshots([items_b])
94+
sushi_context_fixed_date.state_sync.push_snapshots([items_b])
9795

9896
interval_params = scheduler._interval_params([items_a], start_ds, end_ds)
9997
assert len(interval_params) == 1
@@ -113,9 +111,9 @@ def test_multi_version_snapshots(
113111
]
114112

115113

116-
def test_run(sushi_context_pre_scheduling: Context, scheduler: Scheduler):
117-
adapter = sushi_context_pre_scheduling.engine_adapter
118-
snapshot = sushi_context_pre_scheduling.snapshots["sushi.items"]
114+
def test_run(sushi_context_fixed_date: Context, scheduler: Scheduler):
115+
adapter = sushi_context_fixed_date.engine_adapter
116+
snapshot = sushi_context_fixed_date.snapshots["sushi.items"]
119117
scheduler.run(
120118
c.PROD,
121119
"2022-01-01",

tests/core/test_snapshot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def test_fingerprint(model: Model, parent_model: Model):
284284

285285
original_fingerprint = SnapshotFingerprint(
286286
data_hash="3042895307",
287-
metadata_hash="3589467163",
287+
metadata_hash="2417444816",
288288
)
289289

290290
assert fingerprint == original_fingerprint
@@ -363,7 +363,7 @@ def test_fingerprint_jinja_macros(model: Model):
363363

364364
original_fingerprint = SnapshotFingerprint(
365365
data_hash="2665680291",
366-
metadata_hash="3589467163",
366+
metadata_hash="2417444816",
367367
)
368368

369369
fingerprint = fingerprint_from_model(model, models={})

tests/core/test_state_sync.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
)
1515
from sqlmesh.core.snapshot import Snapshot, SnapshotTableInfo
1616
from sqlmesh.core.state_sync import EngineAdapterStateSync
17-
from sqlmesh.utils.date import now_timestamp, to_datetime, to_timestamp
17+
from sqlmesh.utils.date import now_timestamp, to_datetime, to_ds, to_timestamp
1818
from sqlmesh.utils.errors import SQLMeshError
1919

2020

@@ -432,6 +432,41 @@ def test_promote_snapshots_no_gaps(state_sync: EngineAdapterStateSync, make_snap
432432
promote_snapshots(state_sync, [new_snapshot_same_interval], "prod", no_gaps=True)
433433

434434

435+
def test_start_date_gap(state_sync: EngineAdapterStateSync, make_snapshot: t.Callable):
436+
model = SqlModel(
437+
name="a",
438+
query=parse_one("select 1, ds"),
439+
start="2022-01-01",
440+
kind=IncrementalByTimeRangeKind(time_column="ds"),
441+
cron="@daily",
442+
)
443+
444+
snapshot = make_snapshot(model, version="a")
445+
snapshot.add_interval("2022-01-01", "2022-01-03")
446+
state_sync.push_snapshots([snapshot])
447+
promote_snapshots(state_sync, [snapshot], "prod")
448+
449+
model = SqlModel(
450+
name="a",
451+
query=parse_one("select 1, ds"),
452+
start="2022-01-02",
453+
kind=IncrementalByTimeRangeKind(time_column="ds"),
454+
cron="@daily",
455+
)
456+
457+
snapshot = make_snapshot(model, version="b")
458+
snapshot.add_interval("2022-01-03", "2022-01-04")
459+
state_sync.push_snapshots([snapshot])
460+
with pytest.raises(
461+
SQLMeshError,
462+
match=r"Detected gaps in snapshot.*",
463+
):
464+
promote_snapshots(state_sync, [snapshot], "prod", no_gaps=True)
465+
466+
state_sync.add_interval(snapshot, "2022-01-02", "2022-01-03")
467+
promote_snapshots(state_sync, [snapshot], "prod", no_gaps=True)
468+
469+
435470
def test_delete_expired_environments(state_sync: EngineAdapterStateSync, make_snapshot: t.Callable):
436471
snapshot = make_snapshot(
437472
SqlModel(
@@ -472,10 +507,12 @@ def test_delete_expired_environments(state_sync: EngineAdapterStateSync, make_sn
472507
def test_missing_intervals(sushi_context_pre_scheduling: Context) -> None:
473508
sushi_context = sushi_context_pre_scheduling
474509
state_sync = sushi_context.state_reader
475-
missing = state_sync.missing_intervals("prod", "2022-01-01", "2022-01-07", latest="2022-01-07")
510+
start = to_ds("1 week ago")
511+
end = to_ds("yesterday")
512+
missing = state_sync.missing_intervals("prod", start, end, latest=end)
476513
assert missing
477514
assert missing == sushi_context.state_reader.missing_intervals(
478-
sushi_context.snapshots.values(), "2022-01-01", "2022-01-07", "2022-01-07"
515+
sushi_context.snapshots.values(), start, end, end
479516
)
480517

481518

0 commit comments

Comments
 (0)