You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[C++][Python] PyArrow Parquet writer fails writing [null] for null structs, but Datafusion works. Need to add [null] to current working [""] for NULLs. #50470
Describe the bug, including details regarding any error messages, version, and platform.
I'm getting the following error trying to write a parquet file.
pyarrow.lib.ArrowInvalid: Column '_Id' is declare non-nullable, but contains nulls.
I think this is happening because there might be actual nulls in the column for the purpose of making a struct array even between the outer struct and inner struct. The image below is showing is_valid: [false] which looks odd to begin with..
The entire ShareClassType field is nullable and it contains a NULL, but the writer is complaining that a non-nullable field in belonging to non-nullable inner struct contains NULLs.
changed the title [-]PyArrow Parquet writer failing on writing inner structs which are not null, but outer struct is nullable[/-][+][C++][Python] PyArrow Parquet writer failing on writing inner structs which are not null, but outer struct is nullable[/+]on Jul 10, 2026
In PyArrow, a NULL column inside a StructArray is often initialized with a default value like "" (empty string) or 0. This happens because Arrow does not allocate null buffers for nested struct fields; instead, it puts a placeholder in the null slot.To fix this, use PyArrow compute functions to replace the empty strings with proper null values.
I guess using pa.null() or [None] to even out nested struct arrays won't work? I should be adding empty strings instead even though an empty string technically isn't a struct data type?
This could get complex since the outer struct has both scalar types and struct types..
I think this should be fixed in the parquet writer.. The [null] value appear to be perfectly valid in the pyarrow table..
changed the title [-][C++][Python] PyArrow Parquet writer failing on writing inner structs which are not null, but outer struct is nullable[/-][+][C++][Python] PyArrow Parquet writer fails writing [None] for null structs, but Datafusion works. Need to add [None] to current working [""] and [0] for NULLs.[/+]on Jul 10, 2026
changed the title [-][C++][Python] PyArrow Parquet writer fails writing [None] for null structs, but Datafusion works. Need to add [None] to current working [""] and [0] for NULLs.[/-][+][C++][Python] PyArrow Parquet writer fails writing [null] for null structs, but Datafusion works. Need to add [null] to current working [""] and [0] for NULLs.[/+]on Jul 10, 2026
changed the title [-][C++][Python] PyArrow Parquet writer fails writing [null] for null structs, but Datafusion works. Need to add [null] to current working [""] and [0] for NULLs.[/-][+][C++][Python] PyArrow Parquet writer fails writing [null] for null structs, but Datafusion works. Need to add [null] to current working [""] for NULLs.[/+]on Jul 10, 2026
A null parent struct masks its child slots. Therefore, an underlying Arrow child-array slot may be null when the parent struct is null, even if the child field is non-nullable. This is valid because the child is logically absent. The Parquet writer incorrectly rejects this case.
Reproduce
importpyarrowaspaimportpyarrow.parquetaspqvalue_field=pa.field("value", pa.int32(), nullable=False)
# The physical child slot is null.value_column=pa.array([None], type=pa.int32())
# True means that the corresponding parent struct is null.parent_is_null=pa.array([True])
array=pa.StructArray.from_arrays(
arrays=[value_column],
fields=[value_field],
mask=parent_is_null,
)
print("logical array:", array.to_pylist())
print("physical child:", array.field("value").to_pylist())
pq.write_table(pa.table({"data": array}), "output.parquet")
Activity
[-]PyArrow Parquet writer failing on writing inner structs which are not null, but outer struct is nullable[/-][+][C++][Python] PyArrow Parquet writer failing on writing inner structs which are not null, but outer struct is nullable[/+]davlee1972 commentedon Jul 10, 2026
As a temporary work around.. I was able to write the pyarrow table using Datafusion..
Read it back using pyarrow and the rewrite it back as a rowgroup..
Datafusion changed the underlying data to [""].
Schema:
Data:
davlee1972 commentedon Jul 10, 2026
In PyArrow, a NULL column inside a StructArray is often initialized with a default value like "" (empty string) or 0. This happens because Arrow does not allocate null buffers for nested struct fields; instead, it puts a placeholder in the null slot.To fix this, use PyArrow compute functions to replace the empty strings with proper null values.
I guess using pa.null() or [None] to even out nested struct arrays won't work? I should be adding empty strings instead even though an empty string technically isn't a struct data type?
This could get complex since the outer struct has both scalar types and struct types..
I think this should be fixed in the parquet writer.. The [null] value appear to be perfectly valid in the pyarrow table..
[-][C++][Python] PyArrow Parquet writer failing on writing inner structs which are not null, but outer struct is nullable[/-][+][C++][Python] PyArrow Parquet writer fails writing [None] for null structs, but Datafusion works. Need to add [None] to current working [""] and [0] for NULLs.[/+][-][C++][Python] PyArrow Parquet writer fails writing [None] for null structs, but Datafusion works. Need to add [None] to current working [""] and [0] for NULLs.[/-][+][C++][Python] PyArrow Parquet writer fails writing [null] for null structs, but Datafusion works. Need to add [null] to current working [""] and [0] for NULLs.[/+][-][C++][Python] PyArrow Parquet writer fails writing [null] for null structs, but Datafusion works. Need to add [null] to current working [""] and [0] for NULLs.[/-][+][C++][Python] PyArrow Parquet writer fails writing [null] for null structs, but Datafusion works. Need to add [null] to current working [""] for NULLs.[/+]fenfeng9 commentedon Jul 12, 2026
A null parent struct masks its child slots. Therefore, an underlying Arrow child-array slot may be null when the parent struct is null, even if the child field is non-nullable. This is valid because the child is logically absent. The Parquet writer incorrectly rejects this case.
Reproduce
Result
Analysis
This appears to be a regression introduced by #44921.
The check uses
leaf_array.null_count()without accounting for null parent structs, so it incorrectly rejects child nulls masked by a null parent.arrow/cpp/src/parquet/column_writer.cc
Lines 1432 to 1442 in 5815dc0
fenfeng9 commentedon Jul 12, 2026
take
davlee1972 commentedon Oct 26, 2026
#55136
HuaHuaY commentedon Oct 27, 2026
Oh, I didn't notice that an issue already existed.
fenfeng9 commentedon Oct 27, 2026
Thanks for handling this, I’ve been busy lately and totally forgot about this issue — appreciate you picking it up.
HuaHuaY commentedon Oct 27, 2026
#55136 has been merged. I’ve verified that the issue is resolved by building PyArrow locally, so I close this issue.