This is an automated email from the ASF dual-hosted git repository.
tadeja pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 68610e4c2b5 GH-47499: [Python] Explicitly add
`use_content_defined_chunking` to `ParquetWriter` and `write_table` (#47498)
68610e4c2b5 is described below
commit 68610e4c2b59824faf75ba6ace7b792dcff71eea
Author: Sylvain Lesage <[email protected]>
AuthorDate: Thu Sep 17 14:59:30 2026 +0200
GH-47499: [Python] Explicitly add `use_content_defined_chunking` to
`ParquetWriter` and `write_table` (#47498)
### Rationale for this change
The doc page
https://arrow.apache.org/docs/python/generated/pyarrow.parquet.write_table.html
does not show `use_content_defined_chunking` as an argument of `write_table`:
<img width="1571" height="821" alt="Screenshot From 2025-09-04 14-45-32"
src="https://github.com/user-attachments/assets/a9fb4d7f-9b4d-4ce6-92c8-97b781831f33"
/>
Note that it's documented below in the list of parameters:
<img width="1800" height="1062" alt="Screenshot From 2025-09-04 14-46-20"
src="https://github.com/user-attachments/assets/d9d6c289-97c3-476b-820d-eeb30f8f791f"
/>
### What changes are included in this PR?
Change the API signatures of `pyarrow.parquet.ParquetWriter` and
`pyarrow.parquet.write_table`: `use_content_defined_chunking` parameter is
explicitly added, with a default value (`False`), as mentioned by the comment:
https://github.com/apache/arrow/blob/512dcd77dcf3910c41a06d2a1620c729d92d6748/python/pyarrow/parquet/core.py#L1953-L1954
Reorder the parameters in docstring `_parquet_writer_arg_docs` to match the
method signature.
Add a test.
Also users won't get this error anymore `TypeError: unexpected parquet
write option: use_content_defined_chunking` when running with released wheel
(since 21.0.0) :
```shell
python -c "import pyarrow.dataset as ds;
ds.ParquetFileFormat().make_write_options(use_content_defined_chunking=True)"
```
or when running :
```python
import pyarrow as pa, pyarrow.parquet as pq
pq.write_to_dataset(pa.table({'a':[1, 2, 3]}), 'cdc_dataset',
use_content_defined_chunking=True)
```
### Are these changes tested?
Yes
### Are there any user-facing changes?
Yes:
1. `use_content_defined_chunking` parameter is explicitly added to the API
signature and documentation of `pyarrow.parquet.ParquetWriter` and
`pyarrow.parquet.write_table`
2. `use_content_defined_chunking` is now accepted in
`pyarrow.dataset.ParquetFileFormat.make_write_options` and
`pyarrow.parquet.write_to_dataset` instead of raising `TypeError`
* GitHub Issue: #47499
Lead-authored-by: Sylvain Lesage <[email protected]>
Co-authored-by: Tadeja Kadunc <[email protected]>
Signed-off-by: Tadeja Kadunc <[email protected]>
---
python/pyarrow/_dataset_parquet.pyx | 2 +
python/pyarrow/parquet/core.py | 77 +++++++++++++++++++-----------------
python/pyarrow/tests/test_dataset.py | 13 ++++++
3 files changed, 55 insertions(+), 37 deletions(-)
diff --git a/python/pyarrow/_dataset_parquet.pyx
b/python/pyarrow/_dataset_parquet.pyx
index 6ac9383a022..fac8e96df85 100644
--- a/python/pyarrow/_dataset_parquet.pyx
+++ b/python/pyarrow/_dataset_parquet.pyx
@@ -660,6 +660,7 @@ cdef class ParquetFileWriteOptions(FileWriteOptions):
write_page_checksum=self._properties["write_page_checksum"],
sorting_columns=self._properties["sorting_columns"],
store_decimal_as_integer=self._properties["store_decimal_as_integer"],
+
use_content_defined_chunking=self._properties["use_content_defined_chunking"],
)
def _set_arrow_properties(self):
@@ -713,6 +714,7 @@ cdef class ParquetFileWriteOptions(FileWriteOptions):
write_page_checksum=False,
sorting_columns=None,
store_decimal_as_integer=False,
+ use_content_defined_chunking=False,
)
self._set_properties()
diff --git a/python/pyarrow/parquet/core.py b/python/pyarrow/parquet/core.py
index 8e49a96a8f8..152c2694e2a 100644
--- a/python/pyarrow/parquet/core.py
+++ b/python/pyarrow/parquet/core.py
@@ -806,10 +806,6 @@ data_page_size : int, default None
Set a target threshold for the approximate encoded size of data
pages within a column chunk (in bytes). If None, use the default data page
size of 1MByte.
-max_rows_per_page : int, default None
- Maximum number of rows per page within a column chunk.
- If None, use the default of 20000.
- Smaller values reduce memory usage during reads but increase metadata
overhead.
flavor : {'spark'}, default None
Sanitize schema or set other compatibility options to work with
various target systems.
@@ -924,6 +920,42 @@ store_decimal_as_integer : bool, default False
- fixed_len_byte_array: for precision > 18.
As a consequence, decimal columns stored in integer types are more compact.
+write_time_adjusted_to_utc : bool, default False
+ Set the value of isAdjustedTOUTC when writing a TIME column.
+ If True, this tells the Parquet reader that the TIME columns
+ are expressed in reference to midnight in the UTC timezone.
+ If False (the default), the TIME columns are assumed to be expressed
+ in reference to midnight in an unknown, presumably local, timezone.
+max_rows_per_page : int, default None
+ Maximum number of rows per page within a column chunk.
+ If None, use the default of 20000.
+ Smaller values reduce memory usage during reads but increase metadata
overhead.
+bloom_filter_options : dict, default None
+ Create Bloom filters for the columns specified by the provided `dict`.
+
+ Bloom filters can be configured with two parameters: number of distinct
values
+ (NDV), and false-positive probability (FPP).
+
+ Bloom filters are most effective for high-cardinality columns. A good
default
+ is to set NDV equal to the number of rows. Lower values reduce disk usage
but
+ may not be worthwhile for very small NDVs. Increasing NDV (without
increasing FPP)
+ increases disk and memory usage.
+
+ Lower FPP values require more disk and memory space. For a fixed NDV, the
+ space requirement grows roughly proportional to log(1/FPP). Recommended
+ values are 0.1, 0.05, or 0.01. Very small values are counterproductive as
+ the bitset may exceed the size of the actual data. Set NDV appropriately
+ to minimize space usage.
+
+ The keys of the `dict` are column paths. For each path, the value can be
either:
+
+ - A dictionary, with keys `ndv` and `fpp`. The value for `ndv` must be a
positive
+ integer. If the 'ndv' key is not present, the default value of `1048576`
will be
+ used. The value for `fpp` must be a float between 0.0 and 1.0. If the
`fpp` key
+ is not present, the default value of `0.05` will be used.
+ - A boolean, with ``True`` indicating that a Bloom filter should be
produced with
+ the above mentioned default values of `ndv=1048576` and `fpp=0.05`. This
is
+ equivalent to passing an empty dict.
use_content_defined_chunking : bool or dict, default False
Optimize parquet files for content addressable storage (CAS) systems by
writing
data pages according to content-defined chunk boundaries. This allows for
more
@@ -958,39 +990,6 @@ use_content_defined_chunking : bool or dict, default False
balance between deduplication ratio and fragmentation. Use norm_level=1
or
norm_level=2 to reach a higher deduplication ratio at the expense of
fragmentation.
-
-write_time_adjusted_to_utc : bool, default False
- Set the value of isAdjustedTOUTC when writing a TIME column.
- If True, this tells the Parquet reader that the TIME columns
- are expressed in reference to midnight in the UTC timezone.
- If False (the default), the TIME columns are assumed to be expressed
- in reference to midnight in an unknown, presumably local, timezone.
-bloom_filter_options : dict, default None
- Create Bloom filters for the columns specified by the provided `dict`.
-
- Bloom filters can be configured with two parameters: number of distinct
values
- (NDV), and false-positive probability (FPP).
-
- Bloom filters are most effective for high-cardinality columns. A good
default
- is to set NDV equal to the number of rows. Lower values reduce disk usage
but
- may not be worthwhile for very small NDVs. Increasing NDV (without
increasing FPP)
- increases disk and memory usage.
-
- Lower FPP values require more disk and memory space. For a fixed NDV, the
- space requirement grows roughly proportional to log(1/FPP). Recommended
- values are 0.1, 0.05, or 0.01. Very small values are counterproductive as
- the bitset may exceed the size of the actual data. Set NDV appropriately
- to minimize space usage.
-
- The keys of the `dict` are column paths. For each path, the value can be
either:
-
- - A dictionary, with keys `ndv` and `fpp`. The value for `ndv` must be a
positive
- integer. If the 'ndv' key is not present, the default value of `1048576`
will be
- used. The value for `fpp` must be a float between 0.0 and 1.0. If the
`fpp` key
- is not present, the default value of `0.05` will be used.
- - A boolean, with ``True`` indicating that a Bloom filter should be
produced with
- the above mentioned default values of `ndv=1048576` and `fpp=0.05`. This
is
- equivalent to passing an empty dict.
"""
_parquet_writer_example_doc = """\
@@ -1089,6 +1088,7 @@ Examples
store_decimal_as_integer=False,
write_time_adjusted_to_utc=False,
max_rows_per_page=None,
+ use_content_defined_chunking=False,
**options):
if use_deprecated_int96_timestamps is None:
# Use int96 timestamps for Spark
@@ -1144,6 +1144,7 @@ Examples
store_decimal_as_integer=store_decimal_as_integer,
write_time_adjusted_to_utc=write_time_adjusted_to_utc,
max_rows_per_page=max_rows_per_page,
+ use_content_defined_chunking=use_content_defined_chunking,
**options)
self.is_open = True
@@ -2034,6 +2035,7 @@ def write_table(table, where, row_group_size=None,
version='2.6',
write_time_adjusted_to_utc=False,
max_rows_per_page=None,
bloom_filter_options=None,
+ use_content_defined_chunking=False,
**kwargs):
# Implementor's note: when adding keywords here / updating defaults, also
# update it in write_to_dataset and _dataset_parquet.pyx
ParquetFileWriteOptions
@@ -2068,6 +2070,7 @@ def write_table(table, where, row_group_size=None,
version='2.6',
write_time_adjusted_to_utc=write_time_adjusted_to_utc,
max_rows_per_page=max_rows_per_page,
bloom_filter_options=bloom_filter_options,
+ use_content_defined_chunking=use_content_defined_chunking,
**kwargs) as writer:
writer.write_table(table, row_group_size=row_group_size)
except Exception:
diff --git a/python/pyarrow/tests/test_dataset.py
b/python/pyarrow/tests/test_dataset.py
index 1e0fa7c2e24..0a94c0bd987 100644
--- a/python/pyarrow/tests/test_dataset.py
+++ b/python/pyarrow/tests/test_dataset.py
@@ -5936,6 +5936,19 @@ def
test_checksum_write_dataset_read_dataset_to_table(tempdir):
).to_table()
[email protected]
[email protected]("cdc", [
+ True,
+ {"min_chunk_size": 32 * 1024, "max_chunk_size": 64 * 1024},
+])
+def test_write_dataset_content_defined_chunking(tempdir, cdc):
+ expected_table = pa.table({'a': [1, 2, 3]})
+ fmt = ds.ParquetFileFormat()
+ opts = fmt.make_write_options(use_content_defined_chunking=cdc)
+ ds.write_dataset(expected_table, tempdir, format=fmt, file_options=opts)
+ assert ds.dataset(tempdir, format=fmt).to_table().equals(expected_table)
+
+
def test_make_write_options_error():
# GH-39440: calling make_write_options as a static class method
msg_1 = ("make_write_options() should be called on an "