-
Notifications
You must be signed in to change notification settings - Fork 449
Description
Feature Request / Improvement
Make sure that the true/false expression can be serialized to JSON:
iceberg-python/pyiceberg/expressions/__init__.py
Lines 365 to 394 in e5e7453
| class AlwaysTrue(BooleanExpression, Singleton): | |
| """TRUE expression.""" | |
| def __invert__(self) -> AlwaysFalse: | |
| """Transform the Expression into its negated version.""" | |
| return AlwaysFalse() | |
| def __str__(self) -> str: | |
| """Return the string representation of the AlwaysTrue class.""" | |
| return "AlwaysTrue()" | |
| def __repr__(self) -> str: | |
| """Return the string representation of the AlwaysTrue class.""" | |
| return "AlwaysTrue()" | |
| class AlwaysFalse(BooleanExpression, Singleton): | |
| """FALSE expression.""" | |
| def __invert__(self) -> AlwaysTrue: | |
| """Transform the Expression into its negated version.""" | |
| return AlwaysTrue() | |
| def __str__(self) -> str: | |
| """Return the string representation of the AlwaysFalse class.""" | |
| return "AlwaysFalse()" | |
| def __repr__(self) -> str: | |
| """Return the string representation of the AlwaysFalse class.""" | |
| return "AlwaysFalse()" |
This is a special case, since it will not translate into an object, but to a string instead:
"true""false"This so-called root-model (since it doesn't convert to an object), needs to set the root:
iceberg-python/pyiceberg/transforms.py
Lines 579 to 588 in e5e7453
| class DayTransform(TimeTransform[S]): | |
| """Transforms a datetime value into a day value. | |
| Example: | |
| >>> transform = DayTransform() | |
| >>> transform.transform(DateType())(17501) | |
| 17501 | |
| """ | |
| root: LiteralType["day"] = Field(default="day") # noqa: F821 |
We use Pydantic for JSON serialization, which can be enabled by deriving from the IcebergBaseModel:
iceberg-python/pyiceberg/partitioning.py
Line 124 in e5e7453
| class PartitionSpec(IcebergBaseModel): |
Example tests can be found here:
iceberg-python/tests/table/test_partitioning.py
Lines 116 to 132 in e5e7453
| def test_serialize_partition_spec() -> None: | |
| partitioned = PartitionSpec( | |
| PartitionField(source_id=1, field_id=1000, transform=TruncateTransform(width=19), name="str_truncate"), | |
| PartitionField(source_id=2, field_id=1001, transform=BucketTransform(num_buckets=25), name="int_bucket"), | |
| spec_id=3, | |
| ) | |
| assert ( | |
| partitioned.model_dump_json() | |
| == """{"spec-id":3,"fields":[{"source-id":1,"field-id":1000,"transform":"truncate[19]","name":"str_truncate"},{"source-id":2,"field-id":1001,"transform":"bucket[25]","name":"int_bucket"}]}""" | |
| ) | |
| def test_deserialize_unpartition_spec() -> None: | |
| json_partition_spec = """{"spec-id":0,"fields":[]}""" | |
| spec = PartitionSpec.model_validate_json(json_partition_spec) | |
| assert spec == PartitionSpec(spec_id=0) |