mirror of https://github.com/dbcli/pgcli
feat: Replace pendulum by home-made duration-to-words function
`pgcli` uses Pendulum to display the query execution time in words: > select pg_sleep(62) +----------+ | pg_sleep | |----------| | | +----------+ SELECT 1 Time: 62.066s (1 minute 2 seconds), executed in: 62.063s (1 minute 2 seconds) Pendulum 3 (which has been released in December 2023 and is now written in Rust) does not build on 32-bit architectures [1]. As such, installing `pgcli` on such architectures fails. We could pin Pendulum to version 2 (which was written in Python and builds "everywhere"), but requiring a whole library and its own dependencies for such a small feature seems unwarranted. This commit thus removes the requirement on Pendulum and replaces it by a simple "duration-to-words" function. Fixes #1451. [1] Upstream issue: https://github.com/sdispater/pendulum/issues/784
This commit is contained in:
parent
96eb37fd19
commit
9f114c4549
|
@ -67,10 +67,6 @@ jobs:
|
||||||
|
|
||||||
psql -h localhost -U postgres -p 6432 pgbouncer -c 'show help'
|
psql -h localhost -U postgres -p 6432 pgbouncer -c 'show help'
|
||||||
|
|
||||||
- name: Install beta version of pendulum
|
|
||||||
run: pip install pendulum==3.0.0b1
|
|
||||||
if: matrix.python-version == '3.12'
|
|
||||||
|
|
||||||
- name: Install requirements
|
- name: Install requirements
|
||||||
run: |
|
run: |
|
||||||
pip install -U pip setuptools
|
pip install -U pip setuptools
|
||||||
|
|
|
@ -11,6 +11,7 @@ Bug fixes:
|
||||||
* Fix display of "short host" in prompt (with `\h`) for IPv4 addresses ([issue 964](https://github.com/dbcli/pgcli/issues/964)).
|
* Fix display of "short host" in prompt (with `\h`) for IPv4 addresses ([issue 964](https://github.com/dbcli/pgcli/issues/964)).
|
||||||
* Fix backwards display of NOTICEs from a Function ([issue 1443](https://github.com/dbcli/pgcli/issues/1443))
|
* Fix backwards display of NOTICEs from a Function ([issue 1443](https://github.com/dbcli/pgcli/issues/1443))
|
||||||
* Fix psycopg errors when installing on Windows. ([issue 1413](https://https://github.com/dbcli/pgcli/issues/1413))
|
* Fix psycopg errors when installing on Windows. ([issue 1413](https://https://github.com/dbcli/pgcli/issues/1413))
|
||||||
|
* Use a home-made function to display query duration instead of relying on a third-party library (the general behaviour does not change), which fixes the installation of `pgcli` on 32-bit architectures ([issue 1451](https://github.com/dbcli/pgcli/issues/1451))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
4.0.1 (2023-10-30)
|
4.0.1 (2023-10-30)
|
||||||
|
|
|
@ -11,7 +11,6 @@ import logging
|
||||||
import threading
|
import threading
|
||||||
import shutil
|
import shutil
|
||||||
import functools
|
import functools
|
||||||
import pendulum
|
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import itertools
|
import itertools
|
||||||
import platform
|
import platform
|
||||||
|
@ -800,9 +799,9 @@ class PGCli:
|
||||||
"Time: %0.03fs (%s), executed in: %0.03fs (%s)"
|
"Time: %0.03fs (%s), executed in: %0.03fs (%s)"
|
||||||
% (
|
% (
|
||||||
query.total_time,
|
query.total_time,
|
||||||
pendulum.Duration(seconds=query.total_time).in_words(),
|
duration_in_words(query.total_time),
|
||||||
query.execution_time,
|
query.execution_time,
|
||||||
pendulum.Duration(seconds=query.execution_time).in_words(),
|
duration_in_words(query.execution_time),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -1735,5 +1734,28 @@ def parse_service_info(service):
|
||||||
return service_conf, service_file
|
return service_conf, service_file
|
||||||
|
|
||||||
|
|
||||||
|
def duration_in_words(duration_in_seconds: float) -> str:
|
||||||
|
if not duration_in_seconds:
|
||||||
|
return "0 seconds"
|
||||||
|
components = []
|
||||||
|
hours, remainder = divmod(duration_in_seconds, 3600)
|
||||||
|
if hours > 1:
|
||||||
|
components.append(f"{hours} hours")
|
||||||
|
elif hours == 1:
|
||||||
|
components.append("1 hour")
|
||||||
|
minutes, seconds = divmod(remainder, 60)
|
||||||
|
if minutes > 1:
|
||||||
|
components.append(f"{minutes} minutes")
|
||||||
|
elif minutes == 1:
|
||||||
|
components.append("1 minute")
|
||||||
|
if seconds >= 2:
|
||||||
|
components.append(f"{int(seconds)} seconds")
|
||||||
|
elif seconds >= 1:
|
||||||
|
components.append("1 second")
|
||||||
|
elif seconds:
|
||||||
|
components.append(f"{round(seconds, 3)} second")
|
||||||
|
return " ".join(components)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cli()
|
cli()
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -16,7 +16,6 @@ install_requirements = [
|
||||||
"psycopg-binary >= 3.0.14; sys_platform == 'win32'",
|
"psycopg-binary >= 3.0.14; sys_platform == 'win32'",
|
||||||
"sqlparse >=0.3.0,<0.5",
|
"sqlparse >=0.3.0,<0.5",
|
||||||
"configobj >= 5.0.6",
|
"configobj >= 5.0.6",
|
||||||
"pendulum>=2.1.0",
|
|
||||||
"cli_helpers[styles] >= 2.2.1",
|
"cli_helpers[styles] >= 2.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ except ImportError:
|
||||||
|
|
||||||
from pgcli.main import (
|
from pgcli.main import (
|
||||||
obfuscate_process_password,
|
obfuscate_process_password,
|
||||||
|
duration_in_words,
|
||||||
format_output,
|
format_output,
|
||||||
PGCli,
|
PGCli,
|
||||||
OutputSettings,
|
OutputSettings,
|
||||||
|
@ -488,3 +489,28 @@ def test_application_name_db_uri(tmpdir):
|
||||||
mock_pgexecute.assert_called_with(
|
mock_pgexecute.assert_called_with(
|
||||||
"bar", "bar", "", "baz.com", "", "", application_name="cow"
|
"bar", "bar", "", "baz.com", "", "", application_name="cow"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"duration_in_seconds,words",
|
||||||
|
[
|
||||||
|
(0, "0 seconds"),
|
||||||
|
(0.0009, "0.001 second"),
|
||||||
|
(0.0005, "0.001 second"),
|
||||||
|
(0.0004, "0.0 second"), # not perfect, but will do
|
||||||
|
(0.2, "0.2 second"),
|
||||||
|
(1, "1 second"),
|
||||||
|
(1.4, "1 second"),
|
||||||
|
(2, "2 seconds"),
|
||||||
|
(3.4, "3 seconds"),
|
||||||
|
(60, "1 minute"),
|
||||||
|
(61, "1 minute 1 second"),
|
||||||
|
(123, "2 minutes 3 seconds"),
|
||||||
|
(3600, "1 hour"),
|
||||||
|
(7235, "2 hours 35 seconds"),
|
||||||
|
(9005, "2 hours 30 minutes 5 seconds"),
|
||||||
|
(86401, "24 hours 1 second"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_duration_in_words(duration_in_seconds, words):
|
||||||
|
assert duration_in_words(duration_in_seconds) == words
|
||||||
|
|
Loading…
Reference in New Issue