Apache Iceberg version
0.9.0 (latest release)
Please describe the bug 🐞
Description
When using UUIDType as a BucketTransform Partition, an error occurs during table operations such as upsert. The issue appears to be related to the partition key changing from int to str, which causes a type mismatch when the Avro encoder attempts to write an integer.
Steps to Reproduce
- Create a table with UUIDType column
- Configure the table to use BucketTransform on that column for partitioning
- Attempt to upsert data into the table
Current Behavior
The operation fails with a TypeError as the system attempts to perform integer operations on a string value.
Expected Behavior
The operation should properly handle UUIDType columns when used with BucketTransform partitioning. The uuid bucket partition value should be 1 instead of "1"
Error Stack Trace
Traceback (mostrecentcalllast):
File"test_upsert.py", line248, in<module>result=table.upsert(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^File".venv\Lib\site-packages\pyiceberg\table\__init__.py", line1216, inupserttx.append(rows_to_insert)
File".venv\Lib\site-packages\pyiceberg\table\__init__.py", line470, inappendwithself._append_snapshot_producer(snapshot_properties) asappend_files:
File".venv\Lib\site-packages\pyiceberg\table\update\__init__.py", line71, in__exit__self.commit()
File".venv\Lib\site-packages\pyiceberg\table\update\__init__.py", line67, incommitself._transaction._apply(*self._commit())
^^^^^^^^^^^^^^File".venv\Lib\site-packages\pyiceberg\table\update\snapshot.py", line242, in_commitnew_manifests=self._manifests()
^^^^^^^^^^^^^^^^^File".venv\Lib\site-packages\pyiceberg\table\update\snapshot.py", line201, in_manifestsreturnself._process_manifests(added_manifests.result() +delete_manifests.result() +existing_manifests.result())
^^^^^^^^^^^^^^^^^^^^^^^^File"~\Python312\Lib\concurrent\futures\_base.py", line456, inresultreturnself.__get_result()
^^^^^^^^^^^^^^^^^^^File"~\Python312\Lib\concurrent\futures\_base.py", line401, in__get_resultraiseself._exceptionFile"~\Python312\Lib\concurrent\futures\thread.py", line58, inrunresult=self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File".venv\Lib\site-packages\pyiceberg\table\update\snapshot.py", line159, in_write_added_manifestwriter.add(
File".venv\Lib\site-packages\pyiceberg\manifest.py", line847, inaddself.add_entry(self._reused_entry_wrapper._wrap_append(self._snapshot_id, None, entry.data_file))
File".venv\Lib\site-packages\pyiceberg\manifest.py", line840, inadd_entryself._writer.write_block([self.prepare_entry(entry)])
File".venv\Lib\site-packages\pyiceberg\avro\file.py", line281, inwrite_blockself.writer.write(block_content_encoder, obj)
writer.write(encoder, val[pos] ifposisnotNoneelseNone)
File".venv\Lib\site-packages\pyiceberg\avro\writer.py", line176, inwritewriter.write(encoder, val[pos] ifposisnotNoneelseNone)
writer.write(encoder, val[pos] ifposisnotNoneelseNone)
File".venv\Lib\site-packages\pyiceberg\avro\writer.py", line176, inwritewriter.write(encoder, val[pos] ifposisnotNoneelseNone)
File".venv\Lib\site-packages\pyiceberg\avro\writer.py", line66, inwriteencoder.write_int(val)
File".venv\Lib\site-packages\pyiceberg\avro\encoder.py", line45, inwrite_intdatum= (integer<<1) ^ (integer>>63)
Potential Fix
The issue appears to be in the type handling in partition_record_value function when initial PartitionKey with the PartitionFieldValue.
| @dataclass(frozen=True) |
| classPartitionKey: |
| field_values: List[PartitionFieldValue] |
| partition_spec: PartitionSpec |
| schema: Schema |
| |
| @cached_property |
| defpartition(self) ->Record: # partition key transformed with iceberg internal representation as input |
| iceberg_typed_key_values= [] |
| forraw_partition_field_valueinself.field_values: |
| partition_fields=self.partition_spec.source_id_to_fields_map[raw_partition_field_value.field.source_id] |
| iflen(partition_fields) !=1: |
| raiseValueError(f"Cannot have redundant partitions: {partition_fields}") |
| partition_field=partition_fields[0] |
| iceberg_typed_key_values.append( |
| partition_record_value( |
| partition_field=partition_field, |
| value=raw_partition_field_value.value, |
| schema=self.schema, |
| ) |
| ) |
| returnRecord(*iceberg_typed_key_values) |
Would add Union type for value to handle the transformed value.
| @_to_partition_representation.register(UUIDType) |
| def_(type: IcebergType, value: Optional[uuid.UUID]) ->Optional[str]: |
| returnstr(value) ifvalueisnotNoneelseNone |
Willingness to contribute
Apache Iceberg version
0.9.0 (latest release)
Please describe the bug 🐞
Description
When using UUIDType as a BucketTransform Partition, an error occurs during table operations such as upsert. The issue appears to be related to the partition key changing from int to str, which causes a type mismatch when the Avro encoder attempts to write an integer.
Steps to Reproduce
Current Behavior
The operation fails with a TypeError as the system attempts to perform integer operations on a string value.
Expected Behavior
The operation should properly handle UUIDType columns when used with BucketTransform partitioning. The uuid bucket partition value should be
1instead of"1"Error Stack Trace
Potential Fix
The issue appears to be in the type handling in
partition_record_valuefunction when initialPartitionKeywith thePartitionFieldValue.iceberg-python/pyiceberg/partitioning.py
Lines 385 to 406 in 996a7ba
Would add Union type for
valueto handle the transformed value.iceberg-python/pyiceberg/partitioning.py
Lines 469 to 471 in 996a7ba
Willingness to contribute