pgcli 4.2.0__tar.gz → 4.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pgcli-4.2.0 → pgcli-4.3.0}/AUTHORS +3 -0
- {pgcli-4.2.0/pgcli.egg-info → pgcli-4.3.0}/PKG-INFO +5 -3
- {pgcli-4.2.0 → pgcli-4.3.0}/changelog.rst +9 -0
- pgcli-4.3.0/pgcli/__init__.py +1 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/main.py +65 -3
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/pgclirc +9 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/pgexecute.py +13 -0
- {pgcli-4.2.0 → pgcli-4.3.0/pgcli.egg-info}/PKG-INFO +5 -3
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli.egg-info/requires.txt +2 -1
- {pgcli-4.2.0 → pgcli-4.3.0}/pyproject.toml +2 -1
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_main.py +51 -0
- pgcli-4.2.0/pgcli/__init__.py +0 -1
- {pgcli-4.2.0 → pgcli-4.3.0}/LICENSE.txt +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/MANIFEST.in +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/README.rst +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/__main__.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/auth.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/completion_refresher.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/config.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/explain_output_formatter.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/key_bindings.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/magic.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/__init__.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/formatter/__init__.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/formatter/sqlformatter.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/parseutils/__init__.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/parseutils/ctes.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/parseutils/meta.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/parseutils/tables.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/parseutils/utils.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/pgliterals/__init__.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/pgliterals/main.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/pgliterals/pgliterals.json +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/prioritization.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/prompt_utils.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/packages/sqlcompletion.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/pgbuffer.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/pgcompleter.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/pgstyle.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/pgtoolbar.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli/pyev.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli.egg-info/SOURCES.txt +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli.egg-info/dependency_links.txt +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli.egg-info/entry_points.txt +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/pgcli.egg-info/top_level.txt +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/setup.cfg +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/conftest.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/__init__.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/auto_vertical.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/basic_commands.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/crud_database.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/crud_table.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/db_utils.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/environment.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/expanded.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/fixture_data/help.txt +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/fixture_data/help_commands.txt +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/fixture_utils.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/iocommands.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/named_queries.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/pgbouncer.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/specials.feature +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/__init__.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/auto_vertical.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/basic_commands.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/crud_database.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/crud_table.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/expanded.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/iocommands.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/named_queries.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/pgbouncer.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/specials.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/steps/wrappers.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/features/wrappager.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/formatter/__init__.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/formatter/test_sqlformatter.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/metadata.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/parseutils/test_ctes.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/parseutils/test_function_metadata.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/parseutils/test_parseutils.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/pytest.ini +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_application_name.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_auth.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_completion_refresher.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_config.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_fuzzy_completion.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_naive_completion.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_pgcompleter.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_pgexecute.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_pgspecial.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_prioritization.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_prompt_utils.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_rowlimit.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_smart_completion_multiple_schemata.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_smart_completion_public_schema_only.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_sqlcompletion.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/test_ssh_tunnel.py +0 -0
- {pgcli-4.2.0 → pgcli-4.3.0}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pgcli
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: CLI for Postgres Database. With auto-completion and syntax highlighting.
|
|
5
5
|
Author-email: Pgcli Core Team <pgcli-dev@googlegroups.com>
|
|
6
6
|
License: BSD
|
|
@@ -32,12 +32,14 @@ Requires-Dist: psycopg>=3.0.14; sys_platform != "win32"
|
|
|
32
32
|
Requires-Dist: psycopg-binary>=3.0.14; sys_platform == "win32"
|
|
33
33
|
Requires-Dist: sqlparse<0.6,>=0.3.0
|
|
34
34
|
Requires-Dist: configobj>=5.0.6
|
|
35
|
-
Requires-Dist: cli_helpers[styles]>=2.
|
|
35
|
+
Requires-Dist: cli_helpers[styles]>=2.4.0
|
|
36
36
|
Requires-Dist: setproctitle>=1.1.9; sys_platform != "win32" and "CYGWIN" not in sys_platform
|
|
37
|
+
Requires-Dist: tzlocal>=5.2
|
|
37
38
|
Provides-Extra: keyring
|
|
38
39
|
Requires-Dist: keyring>=12.2.0; extra == "keyring"
|
|
39
40
|
Provides-Extra: sshtunnel
|
|
40
41
|
Requires-Dist: sshtunnel>=0.4.0; extra == "sshtunnel"
|
|
42
|
+
Dynamic: license-file
|
|
41
43
|
|
|
42
44
|
We stand with Ukraine
|
|
43
45
|
---------------------
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
4.3.0 (2025-03-22)
|
|
2
|
+
==================
|
|
3
|
+
|
|
4
|
+
Features
|
|
5
|
+
--------
|
|
6
|
+
* The session time zone setting is set to the system time zone by default
|
|
7
|
+
|
|
1
8
|
4.2.0 (2025-03-06)
|
|
2
9
|
==================
|
|
3
10
|
|
|
@@ -5,6 +12,8 @@ Features
|
|
|
5
12
|
--------
|
|
6
13
|
* Add a `--ping` command line option; allows pgcli to replace `pg_isready`
|
|
7
14
|
* Changed the packaging metadata from setup.py to pyproject.toml
|
|
15
|
+
* Add bash completion for services defined in the service file `~/.pg_service.conf`
|
|
16
|
+
* Added support for per-column date/time formatting using `column_date_formats` in config
|
|
8
17
|
|
|
9
18
|
Bug fixes:
|
|
10
19
|
----------
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "4.3.0"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from zoneinfo import ZoneInfoNotFoundError
|
|
1
2
|
from configobj import ConfigObj, ParseError
|
|
2
3
|
from pgspecial.namedqueries import NamedQueries
|
|
3
4
|
from .config import skip_initial_comment
|
|
@@ -19,10 +20,15 @@ from time import time, sleep
|
|
|
19
20
|
from typing import Optional
|
|
20
21
|
|
|
21
22
|
from cli_helpers.tabular_output import TabularOutputFormatter
|
|
22
|
-
from cli_helpers.tabular_output.preprocessors import
|
|
23
|
+
from cli_helpers.tabular_output.preprocessors import (
|
|
24
|
+
align_decimals,
|
|
25
|
+
format_numbers,
|
|
26
|
+
format_timestamps,
|
|
27
|
+
)
|
|
23
28
|
from cli_helpers.utils import strip_ansi
|
|
24
29
|
from .explain_output_formatter import ExplainOutputFormatter
|
|
25
30
|
import click
|
|
31
|
+
import tzlocal
|
|
26
32
|
|
|
27
33
|
try:
|
|
28
34
|
import setproctitle
|
|
@@ -111,12 +117,13 @@ MetaQuery.__new__.__defaults__ = ("", False, 0, 0, False, False, False, False)
|
|
|
111
117
|
|
|
112
118
|
OutputSettings = namedtuple(
|
|
113
119
|
"OutputSettings",
|
|
114
|
-
"table_format dcmlfmt floatfmt missingval expanded max_width case_function style_output max_field_width",
|
|
120
|
+
"table_format dcmlfmt floatfmt column_date_formats missingval expanded max_width case_function style_output max_field_width",
|
|
115
121
|
)
|
|
116
122
|
OutputSettings.__new__.__defaults__ = (
|
|
117
123
|
None,
|
|
118
124
|
None,
|
|
119
125
|
None,
|
|
126
|
+
None,
|
|
120
127
|
"<null>",
|
|
121
128
|
False,
|
|
122
129
|
None,
|
|
@@ -264,6 +271,7 @@ class PGCli:
|
|
|
264
271
|
self.on_error = c["main"]["on_error"].upper()
|
|
265
272
|
self.decimal_format = c["data_formats"]["decimal"]
|
|
266
273
|
self.float_format = c["data_formats"]["float"]
|
|
274
|
+
self.column_date_formats = c["column_date_formats"]
|
|
267
275
|
auth.keyring_initialize(c["main"].as_bool("keyring"), logger=self.logger)
|
|
268
276
|
self.show_bottom_toolbar = c["main"].as_bool("show_bottom_toolbar")
|
|
269
277
|
|
|
@@ -1179,6 +1187,7 @@ class PGCli:
|
|
|
1179
1187
|
table_format=self.table_format,
|
|
1180
1188
|
dcmlfmt=self.decimal_format,
|
|
1181
1189
|
floatfmt=self.float_format,
|
|
1190
|
+
column_date_formats=self.column_date_formats,
|
|
1182
1191
|
missingval=self.null_string,
|
|
1183
1192
|
expanded=expanded,
|
|
1184
1193
|
max_width=max_width,
|
|
@@ -1593,9 +1602,9 @@ def cli(
|
|
|
1593
1602
|
if list_databases or ping_database:
|
|
1594
1603
|
database = "postgres"
|
|
1595
1604
|
|
|
1605
|
+
cfg = load_config(pgclirc, config_full_path)
|
|
1596
1606
|
if dsn != "":
|
|
1597
1607
|
try:
|
|
1598
|
-
cfg = load_config(pgclirc, config_full_path)
|
|
1599
1608
|
dsn_config = cfg["alias_dsn"][dsn]
|
|
1600
1609
|
except KeyError:
|
|
1601
1610
|
click.secho(
|
|
@@ -1624,6 +1633,55 @@ def cli(
|
|
|
1624
1633
|
else:
|
|
1625
1634
|
pgcli.connect(database, host, user, port)
|
|
1626
1635
|
|
|
1636
|
+
if "use_local_timezone" not in cfg["main"] or cfg["main"].as_bool(
|
|
1637
|
+
"use_local_timezone"
|
|
1638
|
+
):
|
|
1639
|
+
server_tz = pgcli.pgexecute.get_timezone()
|
|
1640
|
+
|
|
1641
|
+
def echo_error(msg: str):
|
|
1642
|
+
click.secho(
|
|
1643
|
+
"Failed to determine the local time zone",
|
|
1644
|
+
err=True,
|
|
1645
|
+
fg="yellow",
|
|
1646
|
+
)
|
|
1647
|
+
click.secho(
|
|
1648
|
+
msg,
|
|
1649
|
+
err=True,
|
|
1650
|
+
fg="yellow",
|
|
1651
|
+
)
|
|
1652
|
+
click.secho(
|
|
1653
|
+
f"Continuing with the default time zone as preset by the server ({server_tz})",
|
|
1654
|
+
err=True,
|
|
1655
|
+
fg="yellow",
|
|
1656
|
+
)
|
|
1657
|
+
click.secho(
|
|
1658
|
+
"Set `use_local_timezone = False` in the config to avoid trying to override the server time zone\n",
|
|
1659
|
+
err=True,
|
|
1660
|
+
dim=True,
|
|
1661
|
+
)
|
|
1662
|
+
|
|
1663
|
+
local_tz = None
|
|
1664
|
+
try:
|
|
1665
|
+
local_tz = tzlocal.get_localzone_name()
|
|
1666
|
+
|
|
1667
|
+
if local_tz is None:
|
|
1668
|
+
echo_error("No local time zone configuration found\n")
|
|
1669
|
+
else:
|
|
1670
|
+
click.secho(
|
|
1671
|
+
f"Using local time zone {local_tz} (server uses {server_tz})",
|
|
1672
|
+
fg="green",
|
|
1673
|
+
)
|
|
1674
|
+
click.secho(
|
|
1675
|
+
"Use `set time zone <TZ>` to override, or set `use_local_timezone = False` in the config",
|
|
1676
|
+
dim=True,
|
|
1677
|
+
)
|
|
1678
|
+
|
|
1679
|
+
pgcli.pgexecute.set_timezone(local_tz)
|
|
1680
|
+
except ZoneInfoNotFoundError as e:
|
|
1681
|
+
# e.args[0] is the pre-formatted message which includes a list
|
|
1682
|
+
# of conflicting sources
|
|
1683
|
+
echo_error(e.args[0])
|
|
1684
|
+
|
|
1627
1685
|
if list_databases:
|
|
1628
1686
|
cur, headers, status = pgcli.pgexecute.full_databases()
|
|
1629
1687
|
|
|
@@ -1830,6 +1888,7 @@ def format_output(title, cur, headers, status, settings, explain_mode=False):
|
|
|
1830
1888
|
"missing_value": settings.missingval,
|
|
1831
1889
|
"integer_format": settings.dcmlfmt,
|
|
1832
1890
|
"float_format": settings.floatfmt,
|
|
1891
|
+
"column_date_formats": settings.column_date_formats,
|
|
1833
1892
|
"preprocessors": (format_numbers, format_arrays),
|
|
1834
1893
|
"disable_numparse": True,
|
|
1835
1894
|
"preserve_whitespace": True,
|
|
@@ -1839,6 +1898,9 @@ def format_output(title, cur, headers, status, settings, explain_mode=False):
|
|
|
1839
1898
|
if not settings.floatfmt:
|
|
1840
1899
|
output_kwargs["preprocessors"] = (align_decimals,)
|
|
1841
1900
|
|
|
1901
|
+
if settings.column_date_formats:
|
|
1902
|
+
output_kwargs["preprocessors"] += (format_timestamps,)
|
|
1903
|
+
|
|
1842
1904
|
if table_format == "csv":
|
|
1843
1905
|
# The default CSV dialect is "excel" which is not handling newline values correctly
|
|
1844
1906
|
# Nevertheless, we want to keep on using "excel" on Windows since it uses '\r\n'
|
|
@@ -191,6 +191,10 @@ enable_pager = True
|
|
|
191
191
|
# Use keyring to automatically save and load password in a secure manner
|
|
192
192
|
keyring = True
|
|
193
193
|
|
|
194
|
+
# Automatically set the session time zone to the local time zone
|
|
195
|
+
# If unset, uses the server's time zone, which is the Postgres default
|
|
196
|
+
use_local_timezone = True
|
|
197
|
+
|
|
194
198
|
# Custom colors for the completion menu, toolbar, etc.
|
|
195
199
|
[colors]
|
|
196
200
|
completion-menu.completion.current = 'bg:#ffffff #000000'
|
|
@@ -240,3 +244,8 @@ output.null = "#808080"
|
|
|
240
244
|
[data_formats]
|
|
241
245
|
decimal = ""
|
|
242
246
|
float = ""
|
|
247
|
+
|
|
248
|
+
# Per column formats for date/timestamp columns
|
|
249
|
+
[column_date_formats]
|
|
250
|
+
# use strftime format, e.g.
|
|
251
|
+
# created = "%Y-%m-%d"
|
|
@@ -881,3 +881,16 @@ class PGExecute:
|
|
|
881
881
|
|
|
882
882
|
def explain_prefix(self):
|
|
883
883
|
return "EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON) "
|
|
884
|
+
|
|
885
|
+
def get_timezone(self) -> str:
|
|
886
|
+
query = psycopg.sql.SQL("show time zone")
|
|
887
|
+
with self.conn.cursor() as cur:
|
|
888
|
+
cur.execute(query)
|
|
889
|
+
return cur.fetchone()[0]
|
|
890
|
+
|
|
891
|
+
def set_timezone(self, timezone: str):
|
|
892
|
+
query = psycopg.sql.SQL("set time zone {}").format(
|
|
893
|
+
psycopg.sql.Identifier(timezone)
|
|
894
|
+
)
|
|
895
|
+
with self.conn.cursor() as cur:
|
|
896
|
+
cur.execute(query)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pgcli
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: CLI for Postgres Database. With auto-completion and syntax highlighting.
|
|
5
5
|
Author-email: Pgcli Core Team <pgcli-dev@googlegroups.com>
|
|
6
6
|
License: BSD
|
|
@@ -32,12 +32,14 @@ Requires-Dist: psycopg>=3.0.14; sys_platform != "win32"
|
|
|
32
32
|
Requires-Dist: psycopg-binary>=3.0.14; sys_platform == "win32"
|
|
33
33
|
Requires-Dist: sqlparse<0.6,>=0.3.0
|
|
34
34
|
Requires-Dist: configobj>=5.0.6
|
|
35
|
-
Requires-Dist: cli_helpers[styles]>=2.
|
|
35
|
+
Requires-Dist: cli_helpers[styles]>=2.4.0
|
|
36
36
|
Requires-Dist: setproctitle>=1.1.9; sys_platform != "win32" and "CYGWIN" not in sys_platform
|
|
37
|
+
Requires-Dist: tzlocal>=5.2
|
|
37
38
|
Provides-Extra: keyring
|
|
38
39
|
Requires-Dist: keyring>=12.2.0; extra == "keyring"
|
|
39
40
|
Provides-Extra: sshtunnel
|
|
40
41
|
Requires-Dist: sshtunnel>=0.4.0; extra == "sshtunnel"
|
|
42
|
+
Dynamic: license-file
|
|
41
43
|
|
|
42
44
|
We stand with Ukraine
|
|
43
45
|
---------------------
|
|
@@ -34,12 +34,13 @@ dependencies = [
|
|
|
34
34
|
"psycopg-binary >= 3.0.14; sys_platform == 'win32'",
|
|
35
35
|
"sqlparse >=0.3.0,<0.6",
|
|
36
36
|
"configobj >= 5.0.6",
|
|
37
|
-
"cli_helpers[styles] >= 2.
|
|
37
|
+
"cli_helpers[styles] >= 2.4.0",
|
|
38
38
|
# setproctitle is used to mask the password when running `ps` in command line.
|
|
39
39
|
# But this is not necessary in Windows since the password is never shown in the
|
|
40
40
|
# task manager. Also setproctitle is a hard dependency to install in Windows,
|
|
41
41
|
# so we'll only install it if we're not in Windows.
|
|
42
42
|
"setproctitle >= 1.1.9; sys_platform != 'win32' and 'CYGWIN' not in sys_platform",
|
|
43
|
+
"tzlocal >= 5.2",
|
|
43
44
|
]
|
|
44
45
|
dynamic = ["version"]
|
|
45
46
|
|
|
@@ -76,6 +76,57 @@ def test_format_output():
|
|
|
76
76
|
assert list(results) == expected
|
|
77
77
|
|
|
78
78
|
|
|
79
|
+
def test_column_date_formats():
|
|
80
|
+
settings = OutputSettings(
|
|
81
|
+
table_format="psql",
|
|
82
|
+
column_date_formats={
|
|
83
|
+
"date_col": "%Y-%m-%d",
|
|
84
|
+
"datetime_col": "%I:%M:%S %m/%d/%y",
|
|
85
|
+
},
|
|
86
|
+
)
|
|
87
|
+
data = [
|
|
88
|
+
("name1", "2024-12-13T18:32:22", "2024-12-13T19:32:22", "2024-12-13T20:32:22"),
|
|
89
|
+
("name2", "2025-02-13T02:32:22", "2025-02-13T02:32:22", "2025-02-13T02:32:22"),
|
|
90
|
+
]
|
|
91
|
+
headers = ["name", "date_col", "datetime_col", "unchanged_col"]
|
|
92
|
+
|
|
93
|
+
results = format_output("Title", data, headers, "test status", settings)
|
|
94
|
+
expected = [
|
|
95
|
+
"Title",
|
|
96
|
+
"+-------+------------+-------------------+---------------------+",
|
|
97
|
+
"| name | date_col | datetime_col | unchanged_col |",
|
|
98
|
+
"|-------+------------+-------------------+---------------------|",
|
|
99
|
+
"| name1 | 2024-12-13 | 07:32:22 12/13/24 | 2024-12-13T20:32:22 |",
|
|
100
|
+
"| name2 | 2025-02-13 | 02:32:22 02/13/25 | 2025-02-13T02:32:22 |",
|
|
101
|
+
"+-------+------------+-------------------+---------------------+",
|
|
102
|
+
"test status",
|
|
103
|
+
]
|
|
104
|
+
assert list(results) == expected
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def test_no_column_date_formats():
|
|
108
|
+
"""Test that not setting any column date formats returns unaltered datetime columns"""
|
|
109
|
+
settings = OutputSettings(table_format="psql")
|
|
110
|
+
data = [
|
|
111
|
+
("name1", "2024-12-13T18:32:22", "2024-12-13T19:32:22", "2024-12-13T20:32:22"),
|
|
112
|
+
("name2", "2025-02-13T02:32:22", "2025-02-13T02:32:22", "2025-02-13T02:32:22"),
|
|
113
|
+
]
|
|
114
|
+
headers = ["name", "date_col", "datetime_col", "unchanged_col"]
|
|
115
|
+
|
|
116
|
+
results = format_output("Title", data, headers, "test status", settings)
|
|
117
|
+
expected = [
|
|
118
|
+
"Title",
|
|
119
|
+
"+-------+---------------------+---------------------+---------------------+",
|
|
120
|
+
"| name | date_col | datetime_col | unchanged_col |",
|
|
121
|
+
"|-------+---------------------+---------------------+---------------------|",
|
|
122
|
+
"| name1 | 2024-12-13T18:32:22 | 2024-12-13T19:32:22 | 2024-12-13T20:32:22 |",
|
|
123
|
+
"| name2 | 2025-02-13T02:32:22 | 2025-02-13T02:32:22 | 2025-02-13T02:32:22 |",
|
|
124
|
+
"+-------+---------------------+---------------------+---------------------+",
|
|
125
|
+
"test status",
|
|
126
|
+
]
|
|
127
|
+
assert list(results) == expected
|
|
128
|
+
|
|
129
|
+
|
|
79
130
|
def test_format_output_truncate_on():
|
|
80
131
|
settings = OutputSettings(
|
|
81
132
|
table_format="psql", dcmlfmt="d", floatfmt="g", max_field_width=10
|
pgcli-4.2.0/pgcli/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "4.2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|