dbcli/mycli

Numeric Alignment Incorrect In Table Output

DCEmilberg opened this issue · 2 comments

Hi, I just started using mycli and it is super slick. One thing that caught my eye early on is that numbers are not right aligned, compare what I see from mycli 1.22.2:

(none)> select 'left' `character`, 1 `integer`, 1.0 `double`;
+-----------+---------+--------+
| character | integer | double |
+-----------+---------+--------+
| left      | 1       | 1.0    |
+-----------+---------+--------+

With what the default mysql client shows (notice the numbers are right aligned):

mysql> select 'left' `character`, 1 `integer`, 1.0 `double`;
+-----------+---------+--------+
| character | integer | double |
+-----------+---------+--------+
| left      |       1 |    1.0 |
+-----------+---------+--------+

It's particularly jarring when there are multiple rows with different magnitudes, e.g.:

+-----------------+
| wind_speed_mean |
+-----------------+
| 5               |
| 7               |
| 9               |
| 4               |
| 4               |
| 9               |
| 9               |
| 14              |
| 12              |
| 11              |
| 15              |
| 10              |
| 8               |
| 5               |
| 8               |
| 7               |
| 6               |
| 7               |
| 7               |
| 7               |
+-----------------+

Based on screenshots I'm seeing elsewhere this is either a regression or something specific to my situation (although I'm using all defaults settings). Related issue: #635.

mysql-client right-justify the field when the column type is a number (including year, int, float, etc.).
https://github.com/mysql/mysql-server/blob/1bfe02bdad6604d54913c62614bde57a055c8332/client/mysql.cc#L3666-L3671

I read the mycli source code and I found that mycli uses python-tabulate to pretty-print tabular data. tabulate also right-justifies numbers by default.
https://github.com/astanin/python-tabulate/blob/83fd4fb98926c8a6fdf45caa1b91ee8913b64dcb/tabulate/__init__.py#L2024-L2036

However, mycli specify the parameter disable-numparse=True and tabulate does not parse and align numbers. As a result, the numbers are not aligned to right.

mycli/mycli/main.py

Lines 1050 to 1055 in 3f8f166

output_kwargs = {
'dialect': 'unix',
'disable_numparse': True,
'preserve_whitespace': True,
'style': self.output_style
}

IMO, mycli should only disable numparse for non-number fields and thus this problem can be solved. I'm happy to submit a PR if maintainers agree with this idea.


Based on screenshots I'm seeing elsewhere this is either a regression or something specific to my situation

I think this problem has been there since 2017, because the related code does not change since then.


UPDATE(2023-11-08): To fix this problem, I found that cli_helpers also needs to be changed. From the code, we can see that cli_helpers always set numalign to left.
https://github.com/dbcli/cli_helpers/blob/4e2c417f68bc07c72b508e107431569b0783c4ef/cli_helpers/tabular_output/tabulate_adapter.py#L209C11-L209C11

I'm not typically one to comment with a +1, but this hasn't had any activity for 6 months so figured I would.

My usecase is that I'm copy-pasting the table output into a text editor then using diff to compare the outputs from two separate databases. One environment is set up to have mycli as the default mysql command and the other uses the default mysql client. So with numbers not aligned the same, it makes it slightly more annoying because I need to massage the data by hand a bit to make diff work properly.