Skip to content

GH-49305: [Python] Expose RecordBatchFileReader.count_rows#50646

Draft
GujaLomsadze wants to merge 1 commit into
apache:mainfrom
GujaLomsadze:GH-49305-expose-count-rows
Draft

GH-49305: [Python] Expose RecordBatchFileReader.count_rows#50646
GujaLomsadze wants to merge 1 commit into
apache:mainfrom
GujaLomsadze:GH-49305-expose-count-rows

Conversation

@GujaLomsadze

@GujaLomsadze GujaLomsadze commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Rationale for this change

Resolves 49305

RecordBatchFileReader::CountRows has existed in Arrow C++ (cpp/src/arrow/ipc/reader.h) but
was never bound in Python, so the only way to get the total number of rows of an IPC file was:

num_rows = sum(reader.get_batch(i).num_rows for i in range(reader.num_record_batches))

This findings are done in original opened Issue #49305

That deserializes every record batch just to read its length, which is wasteful and becomes
expensive on remote filesystems.

What changes are included in this PR?

Adds RecordBatchFileReader.count_rows():

with pa.ipc.open_file(source) as reader:
    reader.count_rows()

Three changes:

  • python/pyarrow/includes/libarrow.pxd: declare CResult[int64_t] CountRows() on
    CRecordBatchFileReader, which was the missing piece.
  • python/pyarrow/ipc.pxi: add count_rows() to _RecordBatchFileReader, released GIL around
    the call, with the same closed reader guard used by the existing stats property
  • python/pyarrow/tests/test_ipc.py: tests.

On the naming: count_rows() follows the C++ method and is consistent with the existing
count_rows() on Dataset, Scanner and Fragment.

To be precise about the benefit, since the issue describes it as reading the count from the
metadata: the C++ implementation still walks every block, but reads only each record batch's
flatbuffer message header to pick up its length, and never touches the data buffers. So this is
a reduction in bytes read rather than in the number of reads, and the gain shows up on remote
filesystems and on files with large batches rather than in a local in memory benchmark.

This is only added to the file reader. The stream reader has no footer and cannot count rows
without consuming the stream.

Are these changes tested?

Yes, two tests in python/pyarrow/tests/test_ipc.py:

  • test_file_count_rows: count matches the sum of the written batch lengths, and counting does
    not consume the reader (count, read_all(), count again).
  • test_file_count_rows_no_batches: a file with a schema but no batches counts 0.

Locally test_ipc.py passes (72 tests) and test_feather.py passes (83 passed, 8 skipped,
1 xfailed), the latter because the feather reader sits on the same file reader. The docstring
example was run and produces the output shown.

Are there any user-facing changes?

Yes, a new public method RecordBatchFileReader.count_rows(). No existing behaviour changes.

AI usage disclosure

I used Claude Code to locate the unbound C++ method and the place where the declaration was
missing, and to draft the binding, the docstring and the tests. I reviewed the result, rebuilt
PyArrow locally, ran the test suites quoted above, and checked the C++ implementation of
CountRows myself to confirm what it actually does before describing the benefit here.

RecordBatchFileReader::CountRows was already available in Arrow C++ but not
bound in Python, so the only way to get the total number of rows of an IPC
file was to read every record batch and sum num_rows.

Add a count_rows() method that reads only the metadata of each record batch
without deserializing the batches themselves. The method is named after the
C++ API and matches the existing count_rows() methods on Dataset, Scanner
and Fragment.
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #49305 has been automatically assigned in GitHub to PR creator.

@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #49305 has been automatically assigned in GitHub to PR creator.

1 similar comment
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #49305 has been automatically assigned in GitHub to PR creator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Python] Expose RecordBatchFileReader::CountRows in Python

1 participant