Files
Yuxuan Yan f4b7ef3ae6 feat: add pqcat helper to inspect parquet files
A standalone tools/pqcat.py (head/tail/columns/info) wired as `cli.py pqcat`
and runnable directly via a PATH symlink, plus README docs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 15:33:55 +08:00

51 lines
1.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""CLI helper to inspect parquet files, like `cat` for `.pq`."""
import click
import pandas as pd
@click.command(name="pqcat")
@click.argument("path", type=click.Path(exists=True))
@click.option("-n", "--head", "head", type=int, default=None, help="Show only the first N rows")
@click.option("-t", "--tail", "tail", type=int, default=None, help="Show only the last N rows")
@click.option("-c", "--columns", default=None, help="Comma-separated subset of columns to show")
@click.option("--info", is_flag=True, help="Show shape + dtypes instead of the rows")
def pqcat(path, head, tail, columns, info):
"""Dump a parquet file (or partitioned dataset dir) to stdout.
PATH is a single .pq file or a Hive-partitioned dataset directory.
"""
df = pd.read_parquet(path)
if columns:
cols = [c.strip() for c in columns.split(",") if c.strip()]
missing = [c for c in cols if c not in df.columns]
if missing:
raise click.ClickException(f"Columns not found: {', '.join(missing)}")
df = df[cols]
if info:
click.echo(f"path: {path}")
click.echo(f"shape: {df.shape[0]:,} rows x {df.shape[1]} cols")
click.echo("dtypes:")
for name in df.columns:
click.echo(f" {name}: {df[name].dtype}")
return
if head is not None:
df = df.head(head)
elif tail is not None:
df = df.tail(tail)
with pd.option_context(
"display.max_rows", None if (head is None and tail is None) else len(df),
"display.max_columns", None,
"display.width", None,
):
click.echo(df.to_string(index=False))
if __name__ == "__main__":
pqcat()