diff --git a/python/pyarrow/table.pxi b/python/pyarrow/table.pxi index 2e04fa75b8b7..928792c36097 100644 --- a/python/pyarrow/table.pxi +++ b/python/pyarrow/table.pxi @@ -4915,10 +4915,13 @@ cdef class Table(_Tabular): if isinstance(struct_array, Array): return Table.from_batches([RecordBatch.from_struct_array(struct_array)]) else: - return Table.from_batches([ - RecordBatch.from_struct_array(chunk) - for chunk in struct_array.chunks - ]) + return Table.from_batches( + [ + RecordBatch.from_struct_array(chunk) + for chunk in struct_array.chunks + ], + schema=schema(struct_array.type.fields), + ) def to_struct_array(self, max_chunksize=None): """ diff --git a/python/pyarrow/tests/test_table.py b/python/pyarrow/tests/test_table.py index b65fb7d952c8..62534851f780 100644 --- a/python/pyarrow/tests/test_table.py +++ b/python/pyarrow/tests/test_table.py @@ -942,6 +942,23 @@ def test_table_from_struct_array_chunked_array(): )) +def test_table_from_struct_array_for_empty_chunked_array(): + # GH-48344: round-trip Table.to_struct_array -> Table.from_struct_array + # for an empty table produces a ChunkedArray with zero chunks, which + # previously raised "Must pass schema, or at least one RecordBatch". + struct_type = pa.struct([("ints", pa.int32()), ("floats", pa.float32())]) + empty_chunked_struct_array = pa.chunked_array([], type=struct_type) + result = pa.Table.from_struct_array(empty_chunked_struct_array) + expected = pa.Table.from_arrays( + [ + pa.array([], type=pa.int32()), + pa.array([], type=pa.float32()), + ], ["ints", "floats"] + ) + assert result.equals(expected) + assert result.schema == expected.schema + + def test_table_to_struct_array(): table = pa.Table.from_arrays( [