Skip to content

Commit e27cd90

Browse files
authored
Allow empty names in mapped field of Name Mapping (apache#927)
* Remove check_at_least_one field validator Iceberg spec permits an emtpy list of names in the default name mapping. check_at_least_one is therefore unnecessary. * Remove irrelevant test case * Fixing pydantic model No longer requiring minimum length of names list to be 1. * Added test case for empty names in name mapping * Fixed formatting error
1 parent 3f44dfe commit e27cd90

File tree

2 files changed

+18
-18
lines changed

2 files changed

+18
-18
lines changed

pyiceberg/table/name_mapping.py

+1-13
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,14 @@
3737

3838
class MappedField(IcebergBaseModel):
3939
field_id: int = Field(alias="field-id")
40-
names: List[str] = conlist(str, min_length=1)
40+
names: List[str] = conlist(str)
4141
fields: List[MappedField] = Field(default_factory=list)
4242

4343
@field_validator("fields", mode="before")
4444
@classmethod
4545
def convert_null_to_empty_List(cls, v: Any) -> Any:
4646
return v or []
4747

48-
@field_validator("names", mode="after")
49-
@classmethod
50-
def check_at_least_one(cls, v: List[str]) -> Any:
51-
"""
52-
Conlist constraint does not seem to be validating the class on instantiation.
53-
54-
Adding a custom validator to enforce min_length=1 constraint.
55-
"""
56-
if len(v) < 1:
57-
raise ValueError("At least one mapped name must be provided for the field")
58-
return v
59-
6048
@model_serializer
6149
def ser_model(self) -> Dict[str, Any]:
6250
"""Set custom serializer to leave out the field when it is empty."""

tests/table/test_name_mapping.py

+17-5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,23 @@ def test_json_mapped_field_deserialization() -> None:
9191
assert MappedField(field_id=1, names=["id", "record_id"]) == MappedField.model_validate_json(mapped_field_with_null_fields)
9292

9393

94+
def test_json_mapped_field_no_names_deserialization() -> None:
95+
mapped_field = """{
96+
"field-id": 1,
97+
"names": []
98+
}
99+
"""
100+
assert MappedField(field_id=1, names=[]) == MappedField.model_validate_json(mapped_field)
101+
102+
mapped_field_with_null_fields = """{
103+
"field-id": 1,
104+
"names": [],
105+
"fields": null
106+
}
107+
"""
108+
assert MappedField(field_id=1, names=[]) == MappedField.model_validate_json(mapped_field_with_null_fields)
109+
110+
94111
def test_json_name_mapping_deserialization() -> None:
95112
name_mapping = """
96113
[
@@ -247,11 +264,6 @@ def test_mapping_lookup_by_name(table_name_mapping_nested: NameMapping) -> None:
247264
table_name_mapping_nested.find("boom")
248265

249266

250-
def test_invalid_mapped_field() -> None:
251-
with pytest.raises(ValueError):
252-
MappedField(field_id=1, names=[])
253-
254-
255267
def test_update_mapping_no_updates_or_adds(table_name_mapping_nested: NameMapping) -> None:
256268
assert update_mapping(table_name_mapping_nested, {}, {}) == table_name_mapping_nested
257269

0 commit comments

Comments
 (0)