55
55
from pyiceberg .partitioning import (
56
56
PartitionSpec ,
57
57
)
58
+ from pyiceberg .table .metadata import TableMetadata
58
59
from pyiceberg .table .snapshots import (
59
60
Operation ,
60
61
Snapshot ,
@@ -239,7 +240,21 @@ def _summary(self, snapshot_properties: Dict[str, str] = EMPTY_DICT) -> Summary:
239
240
truncate_full_table = self ._operation == Operation .OVERWRITE ,
240
241
)
241
242
243
+ def refresh (self ) -> TableMetadata :
244
+ try :
245
+ table = self ._transaction ._table .refresh ()
246
+ return table .metadata
247
+ except Exception :
248
+ return self ._transaction ._table .metadata
249
+
250
+ @abstractmethod
251
+ def _validate (self , current_metadata : TableMetadata , Snapshot : Optional [Snapshot ]) -> None : ...
252
+
242
253
def _commit (self ) -> UpdatesAndRequirements :
254
+ current_snapshot = self ._transaction .table_metadata .current_snapshot ()
255
+ table_metadata = self .refresh ()
256
+ self ._validate (table_metadata , current_snapshot )
257
+
243
258
new_manifests = self ._manifests ()
244
259
next_sequence_number = self ._transaction .table_metadata .next_sequence_number ()
245
260
@@ -249,6 +264,7 @@ def _commit(self) -> UpdatesAndRequirements:
249
264
attempt = 0 ,
250
265
commit_uuid = self .commit_uuid ,
251
266
)
267
+
252
268
location_provider = self ._transaction ._table .location_provider ()
253
269
manifest_list_file_path = location_provider .new_metadata_location (file_name )
254
270
with write_manifest_list (
@@ -445,6 +461,14 @@ def files_affected(self) -> bool:
445
461
"""Indicate if any manifest-entries can be dropped."""
446
462
return len (self ._deleted_entries ()) > 0
447
463
464
+ def _validate (self , current_metadata : TableMetadata , Snapshot : Optional [Snapshot ]) -> None :
465
+ if Snapshot is None :
466
+ raise ValueError ("Snapshot cannot be None." )
467
+
468
+ if Snapshot .snapshot_id != current_metadata .snapshot_id :
469
+ raise ValueError ("Operation conflicts are not allowed when performing deleting." )
470
+ return
471
+
448
472
449
473
class _FastAppendFiles (_SnapshotProducer ["_FastAppendFiles" ]):
450
474
def _existing_manifests (self ) -> List [ManifestFile ]:
@@ -474,6 +498,10 @@ def _deleted_entries(self) -> List[ManifestEntry]:
474
498
"""
475
499
return []
476
500
501
+ def _validate (self , current_metadata : TableMetadata , Snapshot : Optional [Snapshot ]) -> None :
502
+ """Other operations don't affect the appending operation, and we can just append."""
503
+ return
504
+
477
505
478
506
class _MergeAppendFiles (_FastAppendFiles ):
479
507
_target_size_bytes : int
@@ -602,6 +630,14 @@ def _get_entries(manifest: ManifestFile) -> List[ManifestEntry]:
602
630
else :
603
631
return []
604
632
633
+ def _validate (self , current_metadata : TableMetadata , Snapshot : Optional [Snapshot ]) -> None :
634
+ if Snapshot is None :
635
+ raise ValueError ("Snapshot cannot be None." )
636
+
637
+ if Snapshot .snapshot_id != current_metadata .snapshot_id :
638
+ raise ValueError ("Operation conflicts are not allowed when performing overwriting." )
639
+ return
640
+
605
641
606
642
class UpdateSnapshot :
607
643
_transaction : Transaction
0 commit comments