Skip to content

Commit cb9891d

Browse files
committed
Add RemovePartitionSpecsUpdate event
1 parent 52d810e commit cb9891d

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
@@ -193,6 +193,11 @@ class RemoveStatisticsUpdate(IcebergBaseModel):
193193
snapshot_id: int = Field(alias="snapshot-id")
194194

195195

196+
class RemovePartitionSpecsUpdate(IcebergBaseModel):
197+
action: Literal["remove-partition-spec"] = Field(default="remove-partition-spec")
198+
spec_ids: List[int] = Field(alias="spec-ids")
199+
200+
196201
class SetPartitionStatisticsUpdate(IcebergBaseModel):
197202
action: Literal["set-partition-statistics"] = Field(default="set-partition-statistics")
198203
partition_statistics: PartitionStatisticsFile
@@ -222,6 +227,7 @@ class RemovePartitionStatisticsUpdate(IcebergBaseModel):
222227
RemovePropertiesUpdate,
223228
SetStatisticsUpdate,
224229
RemoveStatisticsUpdate,
230+
RemovePartitionSpecsUpdate,
225231
SetPartitionStatisticsUpdate,
226232
RemovePartitionStatisticsUpdate,
227233
],
@@ -589,6 +595,21 @@ def _(update: RemoveStatisticsUpdate, base_metadata: TableMetadata, context: _Ta
589595
return base_metadata.model_copy(update={"statistics": statistics})
590596

591597

598+
@_apply_table_update.register(RemovePartitionSpecsUpdate)
599+
def _(update: RemovePartitionSpecsUpdate, base_metadata: TableMetadata, context: _TableMetadataUpdateContext) -> TableMetadata:
600+
for remove_spec_id in update.spec_ids:
601+
if not any(spec.spec_id == remove_spec_id for spec in base_metadata.partition_specs):
602+
raise ValueError(f"Partition spec with id {remove_spec_id} does not exist")
603+
604+
if base_metadata.default_spec_id in update.spec_ids:
605+
raise ValueError(f"Cannot remove default partition spec: {base_metadata.default_spec_id}")
606+
607+
partition_specs = [spec for spec in base_metadata.partition_specs if spec.spec_id not in update.spec_ids]
608+
609+
context.add_update(update)
610+
return base_metadata.model_copy(update={"partition_specs": partition_specs})
611+
612+
592613
@_apply_table_update.register(SetPartitionStatisticsUpdate)
593614
def _(update: SetPartitionStatisticsUpdate, base_metadata: TableMetadata, context: _TableMetadataUpdateContext) -> TableMetadata:
594615
partition_statistics = filter_statistics_by_snapshot_id(

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, PartitionStatisticsFile, 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
RemovePartitionStatisticsUpdate,
8082
RemovePropertiesUpdate,
8183
RemoveSnapshotRefUpdate,
@@ -1286,6 +1288,38 @@ def test_update_metadata_log_overflow(table_v2: Table) -> None:
12861288
assert len(new_metadata.metadata_log) == 1
12871289

12881290

1291+
def test_remove_partition_spec_update(table_v2: Table) -> None:
1292+
base_metadata = table_v2.metadata
1293+
new_spec = PartitionSpec(PartitionField(source_id=2, field_id=1001, transform=IdentityTransform(), name="y"), spec_id=1)
1294+
metadata_with_new_spec = update_table_metadata(base_metadata, (AddPartitionSpecUpdate(spec=new_spec),))
1295+
1296+
assert len(metadata_with_new_spec.partition_specs) == 2
1297+
1298+
update = RemovePartitionSpecsUpdate(spec_ids=[1])
1299+
updated_metadata = update_table_metadata(
1300+
metadata_with_new_spec,
1301+
(update,),
1302+
)
1303+
1304+
assert len(updated_metadata.partition_specs) == 1
1305+
1306+
1307+
def test_remove_partition_spec_update_spec_does_not_exist(table_v2: Table) -> None:
1308+
update = RemovePartitionSpecsUpdate(
1309+
spec_ids=[123],
1310+
)
1311+
with pytest.raises(ValueError, match="Partition spec with id 123 does not exist"):
1312+
update_table_metadata(table_v2.metadata, (update,))
1313+
1314+
1315+
def test_remove_partition_spec_update_default_spec(table_v2: Table) -> None:
1316+
update = RemovePartitionSpecsUpdate(
1317+
spec_ids=[0],
1318+
)
1319+
with pytest.raises(ValueError, match="Cannot remove default partition spec: 0"):
1320+
update_table_metadata(table_v2.metadata, (update,))
1321+
1322+
12891323
def test_set_statistics_update(table_v2_with_statistics: Table) -> None:
12901324
snapshot_id = table_v2_with_statistics.metadata.current_snapshot_id
12911325

0 commit comments

Comments
 (0)