Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions changelog.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Upcoming (TBD)
==============

Features:
---------
* Add ``-t``/``--tuples-only`` CLI option to set table format at startup.
* Sets table format to ``csv-noheader`` (rows only, no headers)
* CLI shortcut equivalent to ``\T csv-noheader``
* Does not suppress timing or status messages (use ``\pset`` for that)

4.4.0 (2025-12-24)
==================

Expand Down
16 changes: 15 additions & 1 deletion pgcli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def __init__(
application_name="pgcli",
single_connection=False,
less_chatty=None,
tuples_only=None,
prompt=None,
prompt_dsn=None,
auto_vertical_output=False,
Expand Down Expand Up @@ -236,7 +237,10 @@ def __init__(

self.min_num_menu_lines = c["main"].as_int("min_num_menu_lines")
self.multiline_continuation_char = c["main"]["multiline_continuation_char"]
self.table_format = c["main"]["table_format"]
if tuples_only:
self.table_format = "csv-noheader"
else:
self.table_format = c["main"]["table_format"]
self.syntax_style = c["main"]["syntax_style"]
self.cli_style = c["colors"]
self.wider_completion_menu = c["main"].as_bool("wider_completion_menu")
Expand Down Expand Up @@ -1429,6 +1433,14 @@ def echo_via_pager(self, text, color=None):
default=False,
help="Skip intro on startup and goodbye on exit.",
)
@click.option(
"-t",
"--tuples-only",
"tuples_only",
is_flag=True,
default=False,
help="Print rows only, using csv-noheader format. Same as \\T csv-noheader.",
)
@click.option("--prompt", help='Prompt format (Default: "\\u@\\h:\\d> ").')
@click.option(
"--prompt-dsn",
Expand Down Expand Up @@ -1492,6 +1504,7 @@ def cli(
row_limit,
application_name,
less_chatty,
tuples_only,
prompt,
prompt_dsn,
list_databases,
Expand Down Expand Up @@ -1554,6 +1567,7 @@ def cli(
application_name=application_name,
single_connection=single_connection,
less_chatty=less_chatty,
tuples_only=tuples_only,
prompt=prompt,
prompt_dsn=prompt_dsn,
auto_vertical_output=auto_vertical_output,
Expand Down
44 changes: 44 additions & 0 deletions tests/test_tuples_only.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from unittest.mock import patch

from click.testing import CliRunner

from pgcli.main import cli, PGCli


def test_tuples_only_flag_passed_to_pgcli():
"""Test that -t passes tuples_only=True to PGCli."""
runner = CliRunner()
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
runner.invoke(cli, ["-t", "mydb"])
call_kwargs = mock_pgcli.call_args[1]
assert call_kwargs["tuples_only"] is True


def test_tuples_only_long_form():
"""Test that --tuples-only passes tuples_only=True to PGCli."""
runner = CliRunner()
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
runner.invoke(cli, ["--tuples-only", "mydb"])
call_kwargs = mock_pgcli.call_args[1]
assert call_kwargs["tuples_only"] is True


def test_tuples_only_not_set_by_default():
"""Test that tuples_only is False when -t is not used."""
runner = CliRunner()
with patch.object(PGCli, "__init__", autospec=True, return_value=None) as mock_pgcli:
runner.invoke(cli, ["mydb"])
call_kwargs = mock_pgcli.call_args[1]
assert call_kwargs["tuples_only"] is False


def test_tuples_only_sets_csv_noheader_format():
"""Test that tuples_only=True sets table_format to csv-noheader."""
pgcli = PGCli(tuples_only=True)
assert pgcli.table_format == "csv-noheader"


def test_default_table_format_without_tuples_only():
"""Test that table_format uses config default when tuples_only is False."""
pgcli = PGCli()
assert pgcli.table_format != "csv-noheader" # Uses config default