Skip to content

Commit 58b1dc7

Browse files
committed
feat: add AssertMetadataLocation requirement for table metadata validation
1 parent d2e8579 commit 58b1dc7

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

‎pyiceberg/catalog/rest/__init__.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
from pyiceberg.table.locations import load_location_provider
8484
from pyiceberg.table.metadata import TableMetadata, new_table_metadata
8585
from pyiceberg.table.sorting import UNSORTED_SORT_ORDER, SortOrder, assign_fresh_sort_order_ids
86-
from pyiceberg.table.update import SetTableMetadataLocationUpdate, TableRequirement, TableUpdate
86+
from pyiceberg.table.update import AssertMetadataLocation, SetTableMetadataLocationUpdate, TableRequirement, TableUpdate
8787
from pyiceberg.typedef import EMPTY_DICT, UTF8, IcebergBaseModel, Identifier, Properties
8888
from pyiceberg.types import transform_dict_value_to_str
8989
from pyiceberg.utils.deprecated import deprecation_message
@@ -1203,6 +1203,7 @@ def commit_table(
12031203
io=updated_staged_table.io,
12041204
metadata_path=updated_staged_table.metadata_location,
12051205
)
1206+
requirements = (AssertMetadataLocation(metadata_location=table.metadata_location), *requirements)
12061207
updates = (SetTableMetadataLocationUpdate(metadata_location=updated_staged_table.metadata_location), *updates)
12071208
table_identifier = TableIdentifier(namespace=identifier[:-1], name=identifier[-1])
12081209
table_request = CommitTableRequest(identifier=table_identifier, requirements=requirements, updates=updates)

‎pyiceberg/table/update/__init__.py‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,22 @@ def validate(self, base_metadata: TableMetadata | None) -> None:
911911
)
912912

913913

914+
class AssertMetadataLocation(ValidatableTableRequirement):
915+
"""The table's metadata location must match the requirement's `metadata-location`."""
916+
917+
type: Literal["assert-table-metadata-location"] = Field(default="assert-table-metadata-location")
918+
metadata_location: str = Field(..., alias="metadata-location")
919+
920+
def validate(self, base_metadata: TableMetadata | None) -> None:
921+
if base_metadata is None:
922+
raise CommitFailedException("Requirement failed: current table metadata is missing")
923+
elif self.metadata_location != base_metadata.metadata_location:
924+
raise CommitFailedException(
925+
f"Requirement failed: metadata location has changed: "
926+
f"expected {self.metadata_location}, found {base_metadata.metadata_location}"
927+
)
928+
929+
914930
TableRequirement = Annotated[
915931
AssertCreate
916932
| AssertTableUUID
@@ -919,7 +935,8 @@ def validate(self, base_metadata: TableMetadata | None) -> None:
919935
| AssertCurrentSchemaId
920936
| AssertLastAssignedPartitionId
921937
| AssertDefaultSpecId
922-
| AssertDefaultSortOrderId,
938+
| AssertDefaultSortOrderId
939+
| AssertMetadataLocation,
923940
Field(discriminator="type"),
924941
]
925942

0 commit comments

Comments
 (0)