Skip to content

Commit 9df1bd0

Browse files
committed
Add RemovePartitionSpecsUpdate event
1 parent ca70442 commit 9df1bd0

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

pyiceberg/table/update/__init__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ class RemoveStatisticsUpdate(IcebergBaseModel):
198198
snapshot_id: int = Field(alias="snapshot-id")
199199

200200

201+
class RemovePartitionSpecsUpdate(IcebergBaseModel):
202+
action: Literal["remove-partition-spec"] = Field(default="remove-partition-spec")
203+
spec_ids: List[int] = Field(alias="spec-ids")
204+
205+
201206
TableUpdate = Annotated[
202207
Union[
203208
AssignUUIDUpdate,
@@ -217,6 +222,7 @@ class RemoveStatisticsUpdate(IcebergBaseModel):
217222
RemovePropertiesUpdate,
218223
SetStatisticsUpdate,
219224
RemoveStatisticsUpdate,
225+
RemovePartitionSpecsUpdate,
220226
],
221227
Field(discriminator="action"),
222228
]
@@ -582,6 +588,21 @@ def _(update: RemoveStatisticsUpdate, base_metadata: TableMetadata, context: _Ta
582588
return base_metadata.model_copy(update={"statistics": statistics})
583589

584590

591+
@_apply_table_update.register(RemovePartitionSpecsUpdate)
592+
def _(update: RemovePartitionSpecsUpdate, base_metadata: TableMetadata, context: _TableMetadataUpdateContext) -> TableMetadata:
593+
for remove_spec_id in update.spec_ids:
594+
if not any(spec.spec_id == remove_spec_id for spec in base_metadata.partition_specs):
595+
raise ValueError(f"Partition spec with id {remove_spec_id} does not exist")
596+
597+
if base_metadata.default_spec_id in update.spec_ids:
598+
raise ValueError(f"Cannot remove default partition spec: {base_metadata.default_spec_id}")
599+
600+
partition_specs = [spec for spec in base_metadata.partition_specs if spec.spec_id not in update.spec_ids]
601+
602+
context.add_update(update)
603+
return base_metadata.model_copy(update={"partition_specs": partition_specs})
604+
605+
585606
def update_table_metadata(
586607
base_metadata: TableMetadata,
587608
updates: Tuple[TableUpdate, ...],

tests/table/test_init.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
)
6767
from pyiceberg.table.statistics import BlobMetadata, StatisticsFile
6868
from pyiceberg.table.update import (
69+
AddPartitionSpecUpdate,
6970
AddSnapshotUpdate,
7071
AddSortOrderUpdate,
7172
AssertCreate,
@@ -76,6 +77,7 @@
7677
AssertLastAssignedPartitionId,
7778
AssertRefSnapshotId,
7879
AssertTableUUID,
80+
RemovePartitionSpecsUpdate,
7981
RemovePropertiesUpdate,
8082
RemoveSnapshotRefUpdate,
8183
RemoveSnapshotsUpdate,
@@ -1267,6 +1269,38 @@ def test_update_metadata_log_overflow(table_v2: Table) -> None:
12671269
assert len(new_metadata.metadata_log) == 1
12681270

12691271

1272+
def test_remove_partition_spec_update(table_v2: Table) -> None:
1273+
base_metadata = table_v2.metadata
1274+
new_spec = PartitionSpec(PartitionField(source_id=2, field_id=1001, transform=IdentityTransform(), name="y"), spec_id=1)
1275+
metadata_with_new_spec = update_table_metadata(base_metadata, (AddPartitionSpecUpdate(spec=new_spec),))
1276+
1277+
assert len(metadata_with_new_spec.partition_specs) == 2
1278+
1279+
update = RemovePartitionSpecsUpdate(spec_ids=[1])
1280+
updated_metadata = update_table_metadata(
1281+
metadata_with_new_spec,
1282+
(update,),
1283+
)
1284+
1285+
assert len(updated_metadata.partition_specs) == 1
1286+
1287+
1288+
def test_remove_partition_spec_update_spec_does_not_exist(table_v2: Table) -> None:
1289+
update = RemovePartitionSpecsUpdate(
1290+
spec_ids=[123],
1291+
)
1292+
with pytest.raises(ValueError, match="Partition spec with id 123 does not exist"):
1293+
update_table_metadata(table_v2.metadata, (update,))
1294+
1295+
1296+
def test_remove_partition_spec_update_default_spec(table_v2: Table) -> None:
1297+
update = RemovePartitionSpecsUpdate(
1298+
spec_ids=[0],
1299+
)
1300+
with pytest.raises(ValueError, match="Cannot remove default partition spec: 0"):
1301+
update_table_metadata(table_v2.metadata, (update,))
1302+
1303+
12701304
def test_set_statistics_update(table_v2_with_statistics: Table) -> None:
12711305
snapshot_id = table_v2_with_statistics.metadata.current_snapshot_id
12721306

0 commit comments

Comments
 (0)