Skip to content

Commit 3ffc271

Browse files
timsaucerclaude
andcommitted
feat: add DataFrame.to_string
Return every row as a pretty-printed table, without the row limit that repr() and show() apply. Wraps upstream DataFrame::to_string. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent ee64f9b commit 3ffc271

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

‎crates/core/src/dataframe.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,12 @@ impl PyDataFrame {
709709
.to_pyarrow(py)
710710
}
711711

712+
/// Execute the DataFrame and render every row as a pretty-printed table
713+
fn to_string(&self, py: Python) -> PyDataFusionResult<String> {
714+
let df = self.df.as_ref().clone();
715+
Ok(wait_for_future(py, df.to_string())??)
716+
}
717+
712718
/// Print the result, 20 lines by default
713719
#[pyo3(signature = (num=20))]
714720
fn show(&self, py: Python, num: usize) -> PyDataFusionResult<()> {

‎python/datafusion/dataframe.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,26 @@ def collect_partitioned(self) -> list[list[pa.RecordBatch]]:
10181018
"""
10191019
return self.df.collect_partitioned()
10201020

1021+
def to_string(self) -> str:
1022+
"""Execute the DataFrame and return every row as a text table.
1023+
1024+
Unlike ``repr(df)`` and :py:meth:`show`, the result is not truncated, so
1025+
this collects the whole DataFrame into memory. A DataFrame with no rows
1026+
renders as an empty border with no header.
1027+
1028+
Examples:
1029+
>>> ctx = dfn.SessionContext()
1030+
>>> df = ctx.from_pydict({"a": [1, 2], "b": ["x", None]})
1031+
>>> print(df.to_string())
1032+
+---+---+
1033+
| a | b |
1034+
+---+---+
1035+
| 1 | x |
1036+
| 2 | |
1037+
+---+---+
1038+
"""
1039+
return self.df.to_string()
1040+
10211041
def show(self, num: int = 20) -> None:
10221042
"""Execute the DataFrame and print the result to the console.
10231043

‎python/tests/test_dataframe.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3999,3 +3999,20 @@ def test_unnest_columns_with_recursions(input_data, recursions, expected_a):
39993999
kwargs["recursions"] = recursions
40004000
result = df.unnest_columns("a", **kwargs).collect()[0]
40014001
assert result.column(0).to_pylist() == expected_a
4002+
4003+
4004+
def test_to_string_includes_every_row(ctx):
4005+
n = 500
4006+
df = ctx.from_pydict({"a": list(range(n))})
4007+
text = df.to_string()
4008+
# One row per line between the header and footer borders.
4009+
body = [line for line in text.splitlines() if line.startswith("| ")]
4010+
assert len(body) == n + 1 # header + rows
4011+
assert f"| {n - 1}" in text
4012+
assert "Data truncated" not in text
4013+
4014+
4015+
def test_to_string_empty(ctx):
4016+
# Upstream renders zero rows as a bare border, without the header.
4017+
df = ctx.from_pydict({"a": [1]}).filter(column("a") > literal(5))
4018+
assert df.to_string() == "++\n++"

0 commit comments

Comments
 (0)