pola-rs/polars · error · ValueError

write_parquet with `use_pyarrow=True` allows only boolean va

Error message

write_parquet with `use_pyarrow=True` allows only boolean values for `statistics`

What it means

Raised by DataFrame.write_parquet(use_pyarrow=True) when `statistics` is 'full' or a dict. The pyarrow writer path delegates to pq.write_table and only accepts a boolean statistics flag; the richer native-writer statistics modes (named/dict per-column and 'full') are polars-engine features. The validation fires before any IO, so no partial file is produced.

Source

Thrown at py-polars/src/polars/dataframe/frame.py:4309

        >>> df.write_parquet(
        ...     path,
        ...     partition_by=["watermark"],
        ... )
        """
        if compression is None:
            compression = "uncompressed"
        if isinstance(file, (str, Path)):
            if partition_by is not None or (
                pyarrow_options is not None and pyarrow_options.get("partition_cols")
            ):
                file = normalize_filepath(file, check_not_directory=False)
            else:
                file = normalize_filepath(file)

        if use_pyarrow:
            if statistics == "full" or isinstance(statistics, dict):
                msg = "write_parquet with `use_pyarrow=True` allows only boolean values for `statistics`"
                raise ValueError(msg)
            if metadata is not None:
                msg = "write_parquet with `use_pyarrow=True` cannot be combined with `metadata`"
                raise ValueError(msg)
            if mkdir:
                msg = "write_parquet with `use_pyarrow=True` cannot be combined with `mkdir`"
                raise ValueError(msg)

            tbl = self.to_arrow()
            data = {}

            for i, column in enumerate(tbl):
                # extract the name before casting
                name = f"column_{i}" if column._name is None else column._name

                data[name] = column

            tbl = pa.table(data)

View on GitHub (pinned to df599052da)

Solutions

  1. Use the native writer for rich statistics: drop `use_pyarrow=True` (statistics='full'/dict are polars-side features)
  2. Or keep use_pyarrow=True and pass a boolean: `statistics=True` / `statistics=False`
  3. Set desired statistics on the pyarrow path via pyarrow_options if supported (e.g. version-specific settings), not the polars statistics argument

Example fix

# before
df.write_parquet('f.parquet', use_pyarrow=True, statistics='full')

# after
df.write_parquet('f.parquet', statistics='full')  # native writer supports it
Defensive patterns

Strategy: validation

Validate before calling

if use_pyarrow and (statistics == 'full' or isinstance(statistics, dict)):
    raise ValueError('pyarrow writer accepts only boolean statistics; use the native writer')
df.write_parquet(path, use_pyarrow=use_pyarrow, statistics=statistics)

Try / catch

try:
    df.write_parquet(path, use_pyarrow=True, statistics=statistics)
except ValueError as e:
    if 'allows only boolean values' in str(e):
        df.write_parquet(path, statistics=statistics)  # native writer
    else:
        raise

Prevention

When it happens

Trigger: `df.write_parquet('f.parquet', use_pyarrow=True, statistics='full')`, or `statistics={'a': True}` combined with `use_pyarrow=True`. Also triggered indirectly by pyarrow_options/partition_by flows that force use_pyarrow while a dict statistics config is passed through shared kwargs.

Common situations: Config-driven writers that always set rich statistics but toggle use_pyarrow=True for partitioned output; enabling pyarrow to use options like row_group_size and forgetting the statistics incompatibility; copying parameter sets between native and pyarrow write paths.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/d9fd1e2413ad7a83. Report an issue: GitHub.