sqlmesh 0.209.1.dev23__py3-none-any.whl → 0.209.1.dev25__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.209.1.dev23'
21
- __version_tuple__ = version_tuple = (0, 209, 1, 'dev23')
20
+ __version__ = version = '0.209.1.dev25'
21
+ __version_tuple__ = version_tuple = (0, 209, 1, 'dev25')
@@ -256,7 +256,7 @@ class EngineAdapterStateSync(StateSync):
256
256
  def unpause_snapshots(
257
257
  self, snapshots: t.Collection[SnapshotInfoLike], unpaused_dt: TimeLike
258
258
  ) -> None:
259
- self.snapshot_state.unpause_snapshots(snapshots, unpaused_dt)
259
+ self.snapshot_state.unpause_snapshots(snapshots, unpaused_dt, self.interval_state)
260
260
 
261
261
  def invalidate_environment(self, name: str, protect_prod: bool = True) -> None:
262
262
  self.environment_state.invalidate_environment(name, protect_prod)
@@ -396,7 +396,7 @@ class StateMigrator:
396
396
  if updated_prod_environment:
397
397
  try:
398
398
  self.snapshot_state.unpause_snapshots(
399
- updated_prod_environment.snapshots, now_timestamp()
399
+ updated_prod_environment.snapshots, now_timestamp(), self.interval_state
400
400
  )
401
401
  except Exception:
402
402
  logger.warning("Failed to unpause migrated snapshots", exc_info=True)
@@ -10,7 +10,6 @@ from pydantic import Field
10
10
 
11
11
  from sqlmesh.core.engine_adapter import EngineAdapter
12
12
  from sqlmesh.core.state_sync.db.utils import (
13
- snapshot_name_filter,
14
13
  snapshot_name_version_filter,
15
14
  snapshot_id_filter,
16
15
  fetchone,
@@ -33,13 +32,15 @@ from sqlmesh.core.snapshot import (
33
32
  SnapshotChangeCategory,
34
33
  )
35
34
  from sqlmesh.utils.migration import index_text_type, blob_text_type
36
- from sqlmesh.utils.date import now_timestamp, TimeLike, to_timestamp
35
+ from sqlmesh.utils.date import now_timestamp, TimeLike, now, to_timestamp
37
36
  from sqlmesh.utils.pydantic import PydanticModel
38
37
  from sqlmesh.utils import unique
39
38
 
40
39
  if t.TYPE_CHECKING:
41
40
  import pandas as pd
42
41
 
42
+ from sqlmesh.core.state_sync.db.interval import IntervalState
43
+
43
44
 
44
45
  logger = logging.getLogger(__name__)
45
46
 
@@ -69,7 +70,6 @@ class SnapshotState:
69
70
  "unpaused_ts": exp.DataType.build("bigint"),
70
71
  "ttl_ms": exp.DataType.build("bigint"),
71
72
  "unrestorable": exp.DataType.build("boolean"),
72
- "forward_only": exp.DataType.build("boolean"),
73
73
  }
74
74
 
75
75
  self._auto_restatement_columns_to_types = {
@@ -112,48 +112,84 @@ class SnapshotState:
112
112
  self,
113
113
  snapshots: t.Collection[SnapshotInfoLike],
114
114
  unpaused_dt: TimeLike,
115
+ interval_state: IntervalState,
115
116
  ) -> None:
116
- unrestorable_snapshots_by_forward_only: t.Dict[bool, t.List[str]] = defaultdict(list)
117
+ """Unpauses given snapshots while pausing all other snapshots that share the same version.
117
118
 
118
- for snapshot in snapshots:
119
- # We need to mark all other snapshots that have opposite forward only status as unrestorable
120
- unrestorable_snapshots_by_forward_only[not snapshot.is_forward_only].append(
121
- snapshot.name
122
- )
119
+ Args:
120
+ snapshots: The snapshots to unpause.
121
+ unpaused_dt: The timestamp to unpause the snapshots at.
122
+ interval_state: The interval state to use to remove intervals when needed.
123
+ """
124
+ current_ts = now()
123
125
 
124
- updated_ts = now_timestamp()
125
- unpaused_ts = to_timestamp(unpaused_dt)
126
+ target_snapshot_ids = {s.snapshot_id for s in snapshots}
127
+ same_version_snapshots = self._get_snapshots_with_same_version(
128
+ snapshots, lock_for_update=True
129
+ )
130
+ target_snapshots_by_version = {
131
+ (s.name, s.version): s
132
+ for s in same_version_snapshots
133
+ if s.snapshot_id in target_snapshot_ids
134
+ }
126
135
 
127
- # Pause all snapshots with target names first
128
- for where in snapshot_name_filter(
129
- [s.name for s in snapshots],
130
- batch_size=self.SNAPSHOT_BATCH_SIZE,
131
- ):
132
- self.engine_adapter.update_table(
133
- self.snapshots_table,
134
- {"unpaused_ts": None, "updated_ts": updated_ts},
135
- where=where,
136
- )
136
+ unpaused_snapshots: t.Dict[int, t.List[SnapshotId]] = defaultdict(list)
137
+ paused_snapshots: t.List[SnapshotId] = []
138
+ unrestorable_snapshots: t.List[SnapshotId] = []
139
+
140
+ for snapshot in same_version_snapshots:
141
+ is_target_snapshot = snapshot.snapshot_id in target_snapshot_ids
142
+ if is_target_snapshot and not snapshot.unpaused_ts:
143
+ logger.info("Unpausing snapshot %s", snapshot.snapshot_id)
144
+ snapshot.set_unpaused_ts(unpaused_dt)
145
+ assert snapshot.unpaused_ts is not None
146
+ unpaused_snapshots[snapshot.unpaused_ts].append(snapshot.snapshot_id)
147
+ elif not is_target_snapshot:
148
+ target_snapshot = target_snapshots_by_version[(snapshot.name, snapshot.version)]
149
+ if (
150
+ target_snapshot.normalized_effective_from_ts
151
+ and not target_snapshot.disable_restatement
152
+ ):
153
+ # Making sure that there are no overlapping intervals.
154
+ effective_from_ts = target_snapshot.normalized_effective_from_ts
155
+ logger.info(
156
+ "Removing all intervals after '%s' for snapshot %s, superseded by snapshot %s",
157
+ target_snapshot.effective_from,
158
+ snapshot.snapshot_id,
159
+ target_snapshot.snapshot_id,
160
+ )
161
+ full_snapshot = snapshot.full_snapshot
162
+ interval_state.remove_intervals(
163
+ [
164
+ (
165
+ full_snapshot,
166
+ full_snapshot.get_removal_interval(effective_from_ts, current_ts),
167
+ )
168
+ ]
169
+ )
137
170
 
138
- # Now unpause the target snapshots
139
- self._update_snapshots(
140
- [s.snapshot_id for s in snapshots],
141
- unpaused_ts=unpaused_ts,
142
- updated_ts=updated_ts,
143
- )
171
+ if snapshot.unpaused_ts:
172
+ logger.info("Pausing snapshot %s", snapshot.snapshot_id)
173
+ snapshot.set_unpaused_ts(None)
174
+ paused_snapshots.append(snapshot.snapshot_id)
144
175
 
145
- # Mark unrestorable snapshots
146
- for forward_only, snapshot_names in unrestorable_snapshots_by_forward_only.items():
147
- forward_only_exp = exp.column("forward_only").is_(exp.convert(forward_only))
148
- for where in snapshot_name_filter(
149
- snapshot_names,
150
- batch_size=self.SNAPSHOT_BATCH_SIZE,
151
- ):
152
- self.engine_adapter.update_table(
153
- self.snapshots_table,
154
- {"unrestorable": True, "updated_ts": updated_ts},
155
- where=forward_only_exp.and_(where),
156
- )
176
+ if not snapshot.unrestorable and (
177
+ (target_snapshot.is_forward_only and not snapshot.is_forward_only)
178
+ or (snapshot.is_forward_only and not target_snapshot.is_forward_only)
179
+ ):
180
+ logger.info("Marking snapshot %s as unrestorable", snapshot.snapshot_id)
181
+ snapshot.unrestorable = True
182
+ unrestorable_snapshots.append(snapshot.snapshot_id)
183
+
184
+ if unpaused_snapshots:
185
+ for unpaused_ts, snapshot_ids in unpaused_snapshots.items():
186
+ self._update_snapshots(snapshot_ids, unpaused_ts=unpaused_ts)
187
+
188
+ if paused_snapshots:
189
+ self._update_snapshots(paused_snapshots, unpaused_ts=None)
190
+
191
+ if unrestorable_snapshots:
192
+ self._update_snapshots(unrestorable_snapshots, unrestorable=True)
157
193
 
158
194
  def get_expired_snapshots(
159
195
  self,
@@ -378,8 +414,7 @@ class SnapshotState:
378
414
  **kwargs: t.Any,
379
415
  ) -> None:
380
416
  properties = kwargs
381
- if "updated_ts" not in properties:
382
- properties["updated_ts"] = now_timestamp()
417
+ properties["updated_ts"] = now_timestamp()
383
418
 
384
419
  for where in snapshot_id_filter(
385
420
  self.engine_adapter, snapshots, batch_size=self.SNAPSHOT_BATCH_SIZE
@@ -431,7 +466,6 @@ class SnapshotState:
431
466
  updated_ts,
432
467
  unpaused_ts,
433
468
  unrestorable,
434
- forward_only,
435
469
  next_auto_restatement_ts,
436
470
  ) in fetchall(self.engine_adapter, query):
437
471
  snapshot = parse_snapshot(
@@ -439,7 +473,6 @@ class SnapshotState:
439
473
  updated_ts=updated_ts,
440
474
  unpaused_ts=unpaused_ts,
441
475
  unrestorable=unrestorable,
442
- forward_only=forward_only,
443
476
  next_auto_restatement_ts=next_auto_restatement_ts,
444
477
  )
445
478
  snapshot_id = snapshot.snapshot_id
@@ -469,7 +502,6 @@ class SnapshotState:
469
502
  "updated_ts",
470
503
  "unpaused_ts",
471
504
  "unrestorable",
472
- "forward_only",
473
505
  "next_auto_restatement_ts",
474
506
  )
475
507
  .from_(exp.to_table(self.snapshots_table).as_("snapshots"))
@@ -496,7 +528,6 @@ class SnapshotState:
496
528
  updated_ts,
497
529
  unpaused_ts,
498
530
  unrestorable,
499
- forward_only,
500
531
  next_auto_restatement_ts,
501
532
  ) in fetchall(self.engine_adapter, query):
502
533
  snapshot_id = SnapshotId(name=name, identifier=identifier)
@@ -504,7 +535,6 @@ class SnapshotState:
504
535
  snapshot.updated_ts = updated_ts
505
536
  snapshot.unpaused_ts = unpaused_ts
506
537
  snapshot.unrestorable = unrestorable
507
- snapshot.forward_only = forward_only
508
538
  snapshot.next_auto_restatement_ts = next_auto_restatement_ts
509
539
  cached_snapshots_in_state.add(snapshot_id)
510
540
 
@@ -538,7 +568,6 @@ class SnapshotState:
538
568
  "snapshots.updated_ts",
539
569
  "snapshots.unpaused_ts",
540
570
  "snapshots.unrestorable",
541
- "snapshots.forward_only",
542
571
  "auto_restatements.next_auto_restatement_ts",
543
572
  )
544
573
  .from_(exp.to_table(self.snapshots_table).as_("snapshots"))
@@ -594,7 +623,6 @@ class SnapshotState:
594
623
  "updated_ts",
595
624
  "unpaused_ts",
596
625
  "unrestorable",
597
- "forward_only",
598
626
  )
599
627
  .from_(exp.to_table(self.snapshots_table).as_("snapshots"))
600
628
  .where(where)
@@ -612,10 +640,9 @@ class SnapshotState:
612
640
  updated_ts=updated_ts,
613
641
  unpaused_ts=unpaused_ts,
614
642
  unrestorable=unrestorable,
615
- forward_only=forward_only,
616
643
  snapshot=snapshot,
617
644
  )
618
- for snapshot, name, identifier, version, updated_ts, unpaused_ts, unrestorable, forward_only in snapshot_rows
645
+ for snapshot, name, identifier, version, updated_ts, unpaused_ts, unrestorable in snapshot_rows
619
646
  ]
620
647
 
621
648
 
@@ -624,7 +651,6 @@ def parse_snapshot(
624
651
  updated_ts: int,
625
652
  unpaused_ts: t.Optional[int],
626
653
  unrestorable: bool,
627
- forward_only: bool,
628
654
  next_auto_restatement_ts: t.Optional[int],
629
655
  ) -> Snapshot:
630
656
  return Snapshot(
@@ -633,7 +659,6 @@ def parse_snapshot(
633
659
  "updated_ts": updated_ts,
634
660
  "unpaused_ts": unpaused_ts,
635
661
  "unrestorable": unrestorable,
636
- "forward_only": forward_only,
637
662
  "next_auto_restatement_ts": next_auto_restatement_ts,
638
663
  }
639
664
  )
@@ -648,7 +673,6 @@ def _snapshot_to_json(snapshot: Snapshot) -> str:
648
673
  "updated_ts",
649
674
  "unpaused_ts",
650
675
  "unrestorable",
651
- "forward_only",
652
676
  "next_auto_restatement_ts",
653
677
  }
654
678
  )
@@ -669,7 +693,6 @@ def _snapshots_to_df(snapshots: t.Iterable[Snapshot]) -> pd.DataFrame:
669
693
  "unpaused_ts": snapshot.unpaused_ts,
670
694
  "ttl_ms": snapshot.ttl_ms,
671
695
  "unrestorable": snapshot.unrestorable,
672
- "forward_only": snapshot.forward_only,
673
696
  }
674
697
  for snapshot in snapshots
675
698
  ]
@@ -739,10 +762,19 @@ class SharedVersionSnapshot(PydanticModel):
739
762
  "updated_ts": self.updated_ts,
740
763
  "unpaused_ts": self.unpaused_ts,
741
764
  "unrestorable": self.unrestorable,
742
- "forward_only": self.forward_only,
743
765
  }
744
766
  )
745
767
 
768
+ def set_unpaused_ts(self, unpaused_dt: t.Optional[TimeLike]) -> None:
769
+ """Sets the timestamp for when this snapshot was unpaused.
770
+
771
+ Args:
772
+ unpaused_dt: The datetime object of when this snapshot was unpaused.
773
+ """
774
+ self.unpaused_ts = (
775
+ to_timestamp(self.interval_unit.cron_floor(unpaused_dt)) if unpaused_dt else None
776
+ )
777
+
746
778
  @classmethod
747
779
  def from_snapshot_record(
748
780
  cls,
@@ -753,7 +785,6 @@ class SharedVersionSnapshot(PydanticModel):
753
785
  updated_ts: int,
754
786
  unpaused_ts: t.Optional[int],
755
787
  unrestorable: bool,
756
- forward_only: bool,
757
788
  snapshot: str,
758
789
  ) -> SharedVersionSnapshot:
759
790
  raw_snapshot = json.loads(snapshot)
@@ -772,5 +803,5 @@ class SharedVersionSnapshot(PydanticModel):
772
803
  disable_restatement=raw_node.get("kind", {}).get("disable_restatement", False),
773
804
  effective_from=raw_snapshot.get("effective_from"),
774
805
  raw_snapshot=raw_snapshot,
775
- forward_only=forward_only,
806
+ forward_only=raw_snapshot.get("forward_only", False),
776
807
  )
@@ -22,21 +22,6 @@ except ImportError:
22
22
  T = t.TypeVar("T")
23
23
 
24
24
 
25
- def snapshot_name_filter(
26
- snapshot_names: t.Iterable[str],
27
- batch_size: int,
28
- alias: t.Optional[str] = None,
29
- ) -> t.Iterator[exp.Condition]:
30
- names = sorted(snapshot_names)
31
-
32
- if not names:
33
- yield exp.false()
34
- else:
35
- batches = create_batches(names, batch_size=batch_size)
36
- for names in batches:
37
- yield exp.column("name", table=alias).isin(*names)
38
-
39
-
40
25
  def snapshot_id_filter(
41
26
  engine_adapter: EngineAdapter,
42
27
  snapshot_ids: t.Iterable[SnapshotIdLike],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.209.1.dev23
3
+ Version: 0.209.1.dev25
4
4
  Summary: Next-generation data transformation framework
5
5
  Author-email: "TobikoData Inc." <engineering@tobikodata.com>
6
6
  License: Apache License
@@ -234,7 +234,7 @@ Requires-Dist: python-dotenv
234
234
  Requires-Dist: requests
235
235
  Requires-Dist: rich[jupyter]
236
236
  Requires-Dist: ruamel.yaml
237
- Requires-Dist: sqlglot[rs]~=27.6.0
237
+ Requires-Dist: sqlglot[rs]~=27.7.0
238
238
  Requires-Dist: tenacity
239
239
  Requires-Dist: time-machine
240
240
  Requires-Dist: json-stream
@@ -1,5 +1,5 @@
1
1
  sqlmesh/__init__.py,sha256=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
2
- sqlmesh/_version.py,sha256=tK_OLQD86grjYfwA8_YlBWRqfeXhHCIZLmzfp0qWy4c,530
2
+ sqlmesh/_version.py,sha256=SoXZf_p1XD2NdO1DtqJJbQup20sz7WhcPKxMhj-q4aE,530
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
@@ -112,11 +112,11 @@ sqlmesh/core/state_sync/common.py,sha256=x8Nkox6VmkD-lYZkjRcNe3iVsChR1HBroTorf1k
112
112
  sqlmesh/core/state_sync/export_import.py,sha256=WJ7sFX2b_RPAFE4yspJRi_4JQnaO23xpJgRxwXD0agA,8709
113
113
  sqlmesh/core/state_sync/db/__init__.py,sha256=jGCqKYB7npq4eh6H2LyfBAJWdOP-IFu0DC4CMiQgYvw,107
114
114
  sqlmesh/core/state_sync/db/environment.py,sha256=iTxrdNlKB36S54PUdlqEqlxiAZJtKNExHBtsIbaXT30,13675
115
- sqlmesh/core/state_sync/db/facade.py,sha256=7OMZt_T3TvavxeC95uwBWe7uD_PtgRyf-s7oYrTkVPg,25245
115
+ sqlmesh/core/state_sync/db/facade.py,sha256=WWditN46A9DXHDcHT7kUZaCfkkjcaDfMC9qO1EfH4Og,25266
116
116
  sqlmesh/core/state_sync/db/interval.py,sha256=aMQSF42bVOUU05g7oizcrKR6TBVzR6TJppxzlxkmJFU,17985
117
- sqlmesh/core/state_sync/db/migrator.py,sha256=av5-dw_0T-u171L8Aepv6nDEg14GFVibdM_hYWq3Hz0,18118
118
- sqlmesh/core/state_sync/db/snapshot.py,sha256=Ik8ijrQzpZOGAuJZCzxs0l0jlfFiRdwAJF0FjuaCZzg,28046
119
- sqlmesh/core/state_sync/db/utils.py,sha256=8KjRmOjP5CLuSRkYBUE2k34V-UYB0iSyuO0rWBQ_5pY,4218
117
+ sqlmesh/core/state_sync/db/migrator.py,sha256=2LNUwOBNFkA1ntp-Z93S_OWxFQhOBj3ZD_ZqPCyPEAE,18139
118
+ sqlmesh/core/state_sync/db/snapshot.py,sha256=NsgMbiQGfu64l6zVEO5Ci5CD_A1nCjmkfRIP6cf6bUY,29845
119
+ sqlmesh/core/state_sync/db/utils.py,sha256=204OpT3ISFPCwWP9Aqq8nr6ETl24sbG5uOyo86IJv6E,3819
120
120
  sqlmesh/core/state_sync/db/version.py,sha256=fl5g1tNMYu8O6WTN4J3bciwjGq0c5nZlRDlxxRKGU78,2210
121
121
  sqlmesh/core/test/__init__.py,sha256=e83TJPwPRR_rAG29Y0OVbZb-5oWVBzz-_wrcd22Qk10,418
122
122
  sqlmesh/core/test/context.py,sha256=9mmskKXpzsIkW_I31uN1n3Ioj8ngvyGAqyL_AZvVHpc,2253
@@ -267,7 +267,6 @@ sqlmesh/migrations/v0086_check_deterministic_bug.py,sha256=WiYcmhQD434GXWiiakQtc
267
267
  sqlmesh/migrations/v0087_normalize_blueprint_variables.py,sha256=GI6KKA-6PtONUoOnyvLpRTUmPjbpa-CKhDa0iqJW01U,4421
268
268
  sqlmesh/migrations/v0088_warn_about_variable_python_env_diffs.py,sha256=zCLT6Yqwny73SlfACWjO1bZfs8lZ7gJBov5Iz4akwiQ,3254
269
269
  sqlmesh/migrations/v0089_add_virtual_environment_mode.py,sha256=rm6k7CRy2uHozo1Oy17D8WhiV1JldPNCpJ8PukoHSwM,122
270
- sqlmesh/migrations/v0090_add_forward_only_column.py,sha256=0mzqPAmZS7KkBpb0tox-iLRAH3ZZVR8gWicZY27El_0,3012
271
270
  sqlmesh/schedulers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
272
271
  sqlmesh/utils/__init__.py,sha256=51VqA2etTZ6kX54250s1hN5ui7D89OeUTUQ9kgMze7s,11554
273
272
  sqlmesh/utils/aws.py,sha256=krxyhrKtsMJDEjT567UbGZogjJ9JRHkvAV-Cg3FVndM,1062
@@ -292,7 +291,7 @@ sqlmesh/utils/pydantic.py,sha256=o_NsXbIpDqNpUA1Uc5xF0ZzoXQYYB0DfHwdRxBwXPNk,120
292
291
  sqlmesh/utils/rich.py,sha256=cwQ5nJ6sgz64xHtoh6_ec7ReV5YpsOGhMtUJnwoRfEI,3549
293
292
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
294
293
  sqlmesh/utils/yaml.py,sha256=hvo5lmybYLcIx4p6CQwufS8X4MbwS60lEBnCmYJCXmU,2336
295
- sqlmesh-0.209.1.dev23.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
294
+ sqlmesh-0.209.1.dev25.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
296
295
  sqlmesh_dbt/__init__.py,sha256=awYS5y5mz-1NUmx6i5h5NSTJ7tidRl9NC0FAnFWSF6U,350
297
296
  sqlmesh_dbt/cli.py,sha256=Ekn77WLMmyyr31aoDoWrZp5DS0rfiddy7pNohBK8G0s,2115
298
297
  sqlmesh_dbt/console.py,sha256=1B0B5_R1DlrEkyWVDl8G78-B6_K-ZtLPsQEhqPCfLEU,188
@@ -414,8 +413,8 @@ web/server/api/endpoints/models.py,sha256=kwj0s7uve3iZSMfmjkoPVMFMeY1sD0peTeyrWf
414
413
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
415
414
  web/server/api/endpoints/plan.py,sha256=bbbY50W_2MsZSTxOHWMKz0tbIm75nsRSlPy8GI2fg9Q,9306
416
415
  web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
417
- sqlmesh-0.209.1.dev23.dist-info/METADATA,sha256=4nFKyxDi7qX_O3klhI0Locdt5GgBqsD0k9j4NAO_6hM,26686
418
- sqlmesh-0.209.1.dev23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
419
- sqlmesh-0.209.1.dev23.dist-info/entry_points.txt,sha256=sHAf6tQczIM8xZoduN4qaUjV7QEPVUUW_LCT8EDUMv4,155
420
- sqlmesh-0.209.1.dev23.dist-info/top_level.txt,sha256=RQ-33FPe2IgL0rgossAfJkCRtqslz9b7wFARqiWLC5Q,24
421
- sqlmesh-0.209.1.dev23.dist-info/RECORD,,
416
+ sqlmesh-0.209.1.dev25.dist-info/METADATA,sha256=OlCKVWiOrV3KhwZ6h-Hl7CMB_u1Y6xD6qKtfXGZPZeQ,26686
417
+ sqlmesh-0.209.1.dev25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
418
+ sqlmesh-0.209.1.dev25.dist-info/entry_points.txt,sha256=sHAf6tQczIM8xZoduN4qaUjV7QEPVUUW_LCT8EDUMv4,155
419
+ sqlmesh-0.209.1.dev25.dist-info/top_level.txt,sha256=RQ-33FPe2IgL0rgossAfJkCRtqslz9b7wFARqiWLC5Q,24
420
+ sqlmesh-0.209.1.dev25.dist-info/RECORD,,
@@ -1,100 +0,0 @@
1
- """Add forward_only column to the snapshots table."""
2
-
3
- import json
4
-
5
- from sqlglot import exp
6
-
7
- from sqlmesh.utils.migration import index_text_type, blob_text_type
8
-
9
-
10
- def migrate(state_sync, **kwargs): # type: ignore
11
- import pandas as pd
12
-
13
- engine_adapter = state_sync.engine_adapter
14
- schema = state_sync.schema
15
- snapshots_table = "_snapshots"
16
- if schema:
17
- snapshots_table = f"{schema}.{snapshots_table}"
18
-
19
- alter_table_exp = exp.Alter(
20
- this=exp.to_table(snapshots_table),
21
- kind="TABLE",
22
- actions=[
23
- exp.ColumnDef(
24
- this=exp.to_column("forward_only"),
25
- kind=exp.DataType.build("boolean"),
26
- )
27
- ],
28
- )
29
- engine_adapter.execute(alter_table_exp)
30
-
31
- new_snapshots = []
32
-
33
- for (
34
- name,
35
- identifier,
36
- version,
37
- snapshot,
38
- kind_name,
39
- updated_ts,
40
- unpaused_ts,
41
- ttl_ms,
42
- unrestorable,
43
- forward_only,
44
- ) in engine_adapter.fetchall(
45
- exp.select(
46
- "name",
47
- "identifier",
48
- "version",
49
- "snapshot",
50
- "kind_name",
51
- "updated_ts",
52
- "unpaused_ts",
53
- "ttl_ms",
54
- "unrestorable",
55
- "forward_only",
56
- ).from_(snapshots_table),
57
- quote_identifiers=True,
58
- ):
59
- parsed_snapshot = json.loads(snapshot)
60
-
61
- forward_only = parsed_snapshot.get("forward_only")
62
- if forward_only is None:
63
- forward_only = parsed_snapshot.get("change_category") == 3
64
-
65
- new_snapshots.append(
66
- {
67
- "name": name,
68
- "identifier": identifier,
69
- "version": version,
70
- "snapshot": json.dumps(parsed_snapshot),
71
- "kind_name": kind_name,
72
- "updated_ts": updated_ts,
73
- "unpaused_ts": unpaused_ts,
74
- "ttl_ms": ttl_ms,
75
- "unrestorable": unrestorable,
76
- "forward_only": forward_only,
77
- }
78
- )
79
-
80
- if new_snapshots:
81
- engine_adapter.delete_from(snapshots_table, "TRUE")
82
- index_type = index_text_type(engine_adapter.dialect)
83
- blob_type = blob_text_type(engine_adapter.dialect)
84
-
85
- engine_adapter.insert_append(
86
- snapshots_table,
87
- pd.DataFrame(new_snapshots),
88
- columns_to_types={
89
- "name": exp.DataType.build(index_type),
90
- "identifier": exp.DataType.build(index_type),
91
- "version": exp.DataType.build(index_type),
92
- "snapshot": exp.DataType.build(blob_type),
93
- "kind_name": exp.DataType.build(index_type),
94
- "updated_ts": exp.DataType.build("bigint"),
95
- "unpaused_ts": exp.DataType.build("bigint"),
96
- "ttl_ms": exp.DataType.build("bigint"),
97
- "unrestorable": exp.DataType.build("boolean"),
98
- "forward_only": exp.DataType.build("boolean"),
99
- },
100
- )