Skip to content
Merged
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
8 changes: 8 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
TBD
==============

Features
--------
* Right-align numeric columns, and make the behavior configurable.


1.47.0 (2026/01/24)
==============

Expand Down
10 changes: 10 additions & 0 deletions mycli/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from collections import defaultdict, namedtuple
from decimal import Decimal
from io import TextIOWrapper
import logging
import os
Expand Down Expand Up @@ -160,6 +161,7 @@ def __init__(
self.login_path_as_host = c["main"].as_bool("login_path_as_host")
self.post_redirect_command = c['main'].get('post_redirect_command')
self.null_string = c['main'].get('null_string')
self.numeric_alignment = c['main'].get('numeric_alignment', 'right')

# set ssl_mode if a valid option is provided in a config file, otherwise None
ssl_mode = c["main"].get("ssl_mode", None)
Expand Down Expand Up @@ -831,6 +833,7 @@ def output_res(results: Generator[SQLResult], start: float) -> None:
special.is_expanded_output(),
special.is_redirected(),
self.null_string,
self.numeric_alignment,
max_width,
)

Expand Down Expand Up @@ -868,6 +871,7 @@ def output_res(results: Generator[SQLResult], start: float) -> None:
special.is_expanded_output(),
special.is_redirected(),
self.null_string,
self.numeric_alignment,
max_width,
)
self.echo("")
Expand Down Expand Up @@ -1345,6 +1349,7 @@ def run_query(
special.is_expanded_output(),
special.is_redirected(),
self.null_string,
self.numeric_alignment,
)
for line in output:
self.log_output(line)
Expand All @@ -1364,6 +1369,7 @@ def run_query(
special.is_expanded_output(),
special.is_redirected(),
self.null_string,
self.numeric_alignment,
)
for line in output:
click.echo(line, nl=new_line)
Expand All @@ -1379,6 +1385,7 @@ def format_output(
expanded: bool = False,
is_redirected: bool = False,
null_string: str | None = None,
numeric_alignment: str = 'right',
max_width: int | None = None,
) -> itertools.chain[str]:
if is_redirected:
Expand Down Expand Up @@ -1408,13 +1415,15 @@ def format_output(

if headers or (cur and title):
column_types = None
colalign = None
if isinstance(cur, Cursor):

def get_col_type(col) -> type:
col_type = FIELD_TYPES.get(col[1], str)
return col_type if type(col_type) is type else str

column_types = [get_col_type(tup) for tup in cur.description]
colalign = [numeric_alignment if x in (int, float, Decimal) else 'left' for x in column_types]

if max_width is not None and isinstance(cur, Cursor):
cur = list(cur)
Expand All @@ -1424,6 +1433,7 @@ def get_col_type(col) -> type:
headers,
format_name="vertical" if expanded else None,
column_types=column_types,
colalign=colalign,
**output_kwargs,
)

Expand Down
3 changes: 3 additions & 0 deletions mycli/myclirc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ redirect_format = csv
# empty string, and JSON formats use native nulls.
null_string = <null>

# How to align numeric data in tabular output: right or left.
numeric_alignment = right

# A command to run after a successful output redirect, with {} to be replaced
# with the escaped filename. Mac example: echo {} | pbcopy. Escaping is not
# reliable/safe on Windows.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies = [
"sqlparse>=0.3.0,<0.6.0",
"sqlglot[rs] == 27.*",
"configobj >= 5.0.5",
"cli_helpers[styles] >= 2.7.0",
"cli_helpers[styles] >= 2.8.0",
"pyperclip >= 1.8.1",
"pycryptodomex",
"pyfzf >= 0.3.1",
Expand Down
3 changes: 3 additions & 0 deletions test/myclirc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ redirect_format = csv
# empty string, and JSON formats use native nulls.
null_string = <nope>

# How to align numeric data in tabular output: right or left.
numeric_alignment = right

# A command to run after a successful output redirect, with {} to be replaced
# with the escaped filename. Mac example: echo {} | pbcopy. Escaping is not
# reliable/safe on Windows.
Expand Down
2 changes: 1 addition & 1 deletion test/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ def test_batch_mode_table(executor):
+----------+
| count(*) |
+----------+
| 3 |
| 3 |
+----------+
+-----+
| a |
Expand Down