pgcli 4.1.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.
Files changed (101) hide show
  1. {pgcli-4.1.0 → pgcli-4.3.0}/AUTHORS +7 -0
  2. {pgcli-4.1.0/pgcli.egg-info → pgcli-4.3.0}/PKG-INFO +17 -12
  3. {pgcli-4.1.0 → pgcli-4.3.0}/README.rst +6 -3
  4. {pgcli-4.1.0 → pgcli-4.3.0}/changelog.rst +27 -0
  5. pgcli-4.3.0/pgcli/__init__.py +1 -0
  6. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/main.py +96 -12
  7. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/pgclirc +9 -0
  8. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/pgcompleter.py +15 -8
  9. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/pgexecute.py +13 -0
  10. {pgcli-4.1.0 → pgcli-4.3.0/pgcli.egg-info}/PKG-INFO +17 -12
  11. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli.egg-info/SOURCES.txt +0 -1
  12. pgcli-4.3.0/pgcli.egg-info/dependency_links.txt +1 -0
  13. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli.egg-info/requires.txt +5 -2
  14. pgcli-4.3.0/pyproject.toml +94 -0
  15. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/basic_commands.feature +4 -0
  16. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/basic_commands.py +13 -0
  17. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_main.py +51 -0
  18. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_pgcompleter.py +24 -0
  19. pgcli-4.1.0/pgcli/__init__.py +0 -1
  20. pgcli-4.1.0/pgcli.egg-info/dependency_links.txt +0 -1
  21. pgcli-4.1.0/pyproject.toml +0 -21
  22. pgcli-4.1.0/setup.py +0 -71
  23. {pgcli-4.1.0 → pgcli-4.3.0}/LICENSE.txt +0 -0
  24. {pgcli-4.1.0 → pgcli-4.3.0}/MANIFEST.in +0 -0
  25. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/__main__.py +0 -0
  26. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/auth.py +0 -0
  27. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/completion_refresher.py +0 -0
  28. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/config.py +0 -0
  29. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/explain_output_formatter.py +0 -0
  30. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/key_bindings.py +0 -0
  31. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/magic.py +0 -0
  32. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/__init__.py +0 -0
  33. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/formatter/__init__.py +0 -0
  34. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/formatter/sqlformatter.py +0 -0
  35. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/parseutils/__init__.py +0 -0
  36. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/parseutils/ctes.py +0 -0
  37. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/parseutils/meta.py +0 -0
  38. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/parseutils/tables.py +0 -0
  39. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/parseutils/utils.py +0 -0
  40. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/pgliterals/__init__.py +0 -0
  41. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/pgliterals/main.py +0 -0
  42. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/pgliterals/pgliterals.json +0 -0
  43. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/prioritization.py +0 -0
  44. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/prompt_utils.py +0 -0
  45. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/packages/sqlcompletion.py +0 -0
  46. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/pgbuffer.py +0 -0
  47. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/pgstyle.py +0 -0
  48. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/pgtoolbar.py +0 -0
  49. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli/pyev.py +0 -0
  50. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli.egg-info/entry_points.txt +0 -0
  51. {pgcli-4.1.0 → pgcli-4.3.0}/pgcli.egg-info/top_level.txt +0 -0
  52. {pgcli-4.1.0 → pgcli-4.3.0}/setup.cfg +0 -0
  53. {pgcli-4.1.0 → pgcli-4.3.0}/tests/conftest.py +0 -0
  54. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/__init__.py +0 -0
  55. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/auto_vertical.feature +0 -0
  56. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/crud_database.feature +0 -0
  57. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/crud_table.feature +0 -0
  58. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/db_utils.py +0 -0
  59. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/environment.py +0 -0
  60. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/expanded.feature +0 -0
  61. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/fixture_data/help.txt +0 -0
  62. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/fixture_data/help_commands.txt +0 -0
  63. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/fixture_utils.py +0 -0
  64. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/iocommands.feature +0 -0
  65. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/named_queries.feature +0 -0
  66. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/pgbouncer.feature +0 -0
  67. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/specials.feature +0 -0
  68. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/__init__.py +0 -0
  69. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/auto_vertical.py +0 -0
  70. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/crud_database.py +0 -0
  71. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/crud_table.py +0 -0
  72. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/expanded.py +0 -0
  73. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/iocommands.py +0 -0
  74. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/named_queries.py +0 -0
  75. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/pgbouncer.py +0 -0
  76. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/specials.py +0 -0
  77. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/steps/wrappers.py +0 -0
  78. {pgcli-4.1.0 → pgcli-4.3.0}/tests/features/wrappager.py +0 -0
  79. {pgcli-4.1.0 → pgcli-4.3.0}/tests/formatter/__init__.py +0 -0
  80. {pgcli-4.1.0 → pgcli-4.3.0}/tests/formatter/test_sqlformatter.py +0 -0
  81. {pgcli-4.1.0 → pgcli-4.3.0}/tests/metadata.py +0 -0
  82. {pgcli-4.1.0 → pgcli-4.3.0}/tests/parseutils/test_ctes.py +0 -0
  83. {pgcli-4.1.0 → pgcli-4.3.0}/tests/parseutils/test_function_metadata.py +0 -0
  84. {pgcli-4.1.0 → pgcli-4.3.0}/tests/parseutils/test_parseutils.py +0 -0
  85. {pgcli-4.1.0 → pgcli-4.3.0}/tests/pytest.ini +0 -0
  86. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_application_name.py +0 -0
  87. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_auth.py +0 -0
  88. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_completion_refresher.py +0 -0
  89. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_config.py +0 -0
  90. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_fuzzy_completion.py +0 -0
  91. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_naive_completion.py +0 -0
  92. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_pgexecute.py +0 -0
  93. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_pgspecial.py +0 -0
  94. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_prioritization.py +0 -0
  95. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_prompt_utils.py +0 -0
  96. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_rowlimit.py +0 -0
  97. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_smart_completion_multiple_schemata.py +0 -0
  98. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_smart_completion_public_schema_only.py +0 -0
  99. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_sqlcompletion.py +0 -0
  100. {pgcli-4.1.0 → pgcli-4.3.0}/tests/test_ssh_tunnel.py +0 -0
  101. {pgcli-4.1.0 → pgcli-4.3.0}/tests/utils.py +0 -0
@@ -134,6 +134,13 @@ Contributors:
134
134
  * Antonio Aguilar (crazybolillo)
135
135
  * Andrew M. MacFie (amacfie)
136
136
  * saucoide
137
+ * Chris Rose (offbyone/offby1)
138
+ * Mathieu Dupuy (deronnax)
139
+ * Chris Novakovic
140
+ * Max Smolin (maximsmol)
141
+ * Josh Lynch (josh-lynch)
142
+ * Fabio (3ximus)
143
+ * Doug Harris (dougharris)
137
144
 
138
145
  Creator:
139
146
  --------
@@ -1,27 +1,27 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pgcli
3
- Version: 4.1.0
3
+ Version: 4.3.0
4
4
  Summary: CLI for Postgres Database. With auto-completion and syntax highlighting.
5
- Home-page: http://pgcli.com
6
- Author: Pgcli Core Team
7
- Author-email: pgcli-dev@googlegroups.com
5
+ Author-email: Pgcli Core Team <pgcli-dev@googlegroups.com>
8
6
  License: BSD
7
+ Project-URL: Homepage, https://pgcli.com
9
8
  Classifier: Intended Audience :: Developers
10
9
  Classifier: License :: OSI Approved :: BSD License
11
10
  Classifier: Operating System :: Unix
12
11
  Classifier: Programming Language :: Python
13
12
  Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.8
15
13
  Classifier: Programming Language :: Python :: 3.9
16
14
  Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
18
16
  Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
19
18
  Classifier: Programming Language :: SQL
20
19
  Classifier: Topic :: Database
21
20
  Classifier: Topic :: Database :: Front-Ends
22
21
  Classifier: Topic :: Software Development
23
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
- Requires-Python: >=3.8
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/x-rst
25
25
  License-File: LICENSE.txt
26
26
  License-File: AUTHORS
27
27
  Requires-Dist: pgspecial>=2.0.0
@@ -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.2.1
36
- Requires-Dist: setproctitle>=1.1.9
35
+ Requires-Dist: cli_helpers[styles]>=2.4.0
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
  ---------------------
@@ -220,7 +222,7 @@ Alternatively, you can install ``pgcli`` as a python package using a package
220
222
  manager called called ``pip``. You will need postgres installed on your system
221
223
  for this to work.
222
224
 
223
- In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installing.html.
225
+ In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installation/
224
226
 
225
227
  ::
226
228
 
@@ -250,7 +252,7 @@ If pip is not installed check if easy_install is available on the system.
250
252
  Linux:
251
253
  ======
252
254
 
253
- In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installing.html.
255
+ In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installation/
254
256
 
255
257
  Check if pip is already available in your system.
256
258
 
@@ -393,7 +395,10 @@ choice:
393
395
 
394
396
  In [3]: my_result = _
395
397
 
396
- Pgcli dropped support for Python<3.8 as of 4.0.0. If you need it, install ``pgcli <= 4.0.0``.
398
+ Pgcli dropped support for:
399
+
400
+ * Python<3.8 as of 4.0.0.
401
+ * Python<3.9 as of 4.2.0.
397
402
 
398
403
  Thanks:
399
404
  -------
@@ -179,7 +179,7 @@ Alternatively, you can install ``pgcli`` as a python package using a package
179
179
  manager called called ``pip``. You will need postgres installed on your system
180
180
  for this to work.
181
181
 
182
- In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installing.html.
182
+ In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installation/
183
183
 
184
184
  ::
185
185
 
@@ -209,7 +209,7 @@ If pip is not installed check if easy_install is available on the system.
209
209
  Linux:
210
210
  ======
211
211
 
212
- In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installing.html.
212
+ In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installation/
213
213
 
214
214
  Check if pip is already available in your system.
215
215
 
@@ -352,7 +352,10 @@ choice:
352
352
 
353
353
  In [3]: my_result = _
354
354
 
355
- Pgcli dropped support for Python<3.8 as of 4.0.0. If you need it, install ``pgcli <= 4.0.0``.
355
+ Pgcli dropped support for:
356
+
357
+ * Python<3.8 as of 4.0.0.
358
+ * Python<3.9 as of 4.2.0.
356
359
 
357
360
  Thanks:
358
361
  -------
@@ -1,3 +1,30 @@
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
+
8
+ 4.2.0 (2025-03-06)
9
+ ==================
10
+
11
+ Features
12
+ --------
13
+ * Add a `--ping` command line option; allows pgcli to replace `pg_isready`
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
17
+
18
+ Bug fixes:
19
+ ----------
20
+ * Avoid raising `NameError` when exiting unsuccessfully in some cases
21
+ * Use configured `alias_map_file` to generate table aliases if available.
22
+
23
+ Internal:
24
+ ---------
25
+
26
+ * Drop support for Python 3.8 and add 3.13.
27
+
1
28
  4.1.0 (2024-03-09)
2
29
  ==================
3
30
 
@@ -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 align_decimals, format_numbers
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
 
@@ -610,7 +618,7 @@ class PGCli:
610
618
  click.secho(
611
619
  f"service '{service}' was not found in {file}", err=True, fg="red"
612
620
  )
613
- exit(1)
621
+ sys.exit(1)
614
622
  self.connect(
615
623
  database=service_config.get("dbname"),
616
624
  host=service_config.get("host"),
@@ -710,7 +718,7 @@ class PGCli:
710
718
  self.logger.handlers = logger_handlers
711
719
  self.logger.error("traceback: %r", traceback.format_exc())
712
720
  click.secho(str(e), err=True, fg="red")
713
- exit(1)
721
+ sys.exit(1)
714
722
  self.logger.handlers = logger_handlers
715
723
 
716
724
  atexit.register(self.ssh_tunnel.stop)
@@ -763,7 +771,7 @@ class PGCli:
763
771
  self.logger.debug("Database connection failed: %r.", e)
764
772
  self.logger.error("traceback: %r", traceback.format_exc())
765
773
  click.secho(str(e), err=True, fg="red")
766
- exit(1)
774
+ sys.exit(1)
767
775
 
768
776
  self.pgexecute = pgexecute
769
777
 
@@ -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,
@@ -1463,6 +1472,13 @@ class PGCli:
1463
1472
  is_flag=True,
1464
1473
  help="list available databases, then exit.",
1465
1474
  )
1475
+ @click.option(
1476
+ "--ping",
1477
+ "ping_database",
1478
+ is_flag=True,
1479
+ default=False,
1480
+ help="Check database connectivity, then exit.",
1481
+ )
1466
1482
  @click.option(
1467
1483
  "--auto-vertical-output",
1468
1484
  is_flag=True,
@@ -1504,6 +1520,7 @@ def cli(
1504
1520
  prompt,
1505
1521
  prompt_dsn,
1506
1522
  list_databases,
1523
+ ping_database,
1507
1524
  auto_vertical_output,
1508
1525
  list_dsn,
1509
1526
  warn,
@@ -1543,7 +1560,7 @@ def cli(
1543
1560
  err=True,
1544
1561
  fg="red",
1545
1562
  )
1546
- exit(1)
1563
+ sys.exit(1)
1547
1564
 
1548
1565
  if ssh_tunnel and not SSH_TUNNEL_SUPPORT:
1549
1566
  click.secho(
@@ -1552,7 +1569,7 @@ def cli(
1552
1569
  err=True,
1553
1570
  fg="red",
1554
1571
  )
1555
- exit(1)
1572
+ sys.exit(1)
1556
1573
 
1557
1574
  pgcli = PGCli(
1558
1575
  prompt_passwd,
@@ -1581,13 +1598,13 @@ def cli(
1581
1598
  service = database[8:]
1582
1599
  elif os.getenv("PGSERVICE") is not None:
1583
1600
  service = os.getenv("PGSERVICE")
1584
- # because option --list or -l are not supposed to have a db name
1585
- if list_databases:
1601
+ # because option --ping, --list or -l are not supposed to have a db name
1602
+ if list_databases or ping_database:
1586
1603
  database = "postgres"
1587
1604
 
1605
+ cfg = load_config(pgclirc, config_full_path)
1588
1606
  if dsn != "":
1589
1607
  try:
1590
- cfg = load_config(pgclirc, config_full_path)
1591
1608
  dsn_config = cfg["alias_dsn"][dsn]
1592
1609
  except KeyError:
1593
1610
  click.secho(
@@ -1596,7 +1613,7 @@ def cli(
1596
1613
  err=True,
1597
1614
  fg="red",
1598
1615
  )
1599
- exit(1)
1616
+ sys.exit(1)
1600
1617
  except Exception:
1601
1618
  click.secho(
1602
1619
  "Invalid DSNs found in the config file. "
@@ -1604,7 +1621,7 @@ def cli(
1604
1621
  err=True,
1605
1622
  fg="red",
1606
1623
  )
1607
- exit(1)
1624
+ sys.exit(1)
1608
1625
  pgcli.connect_uri(dsn_config)
1609
1626
  pgcli.dsn_alias = dsn
1610
1627
  elif "://" in database:
@@ -1616,6 +1633,55 @@ def cli(
1616
1633
  else:
1617
1634
  pgcli.connect(database, host, user, port)
1618
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
+
1619
1685
  if list_databases:
1620
1686
  cur, headers, status = pgcli.pgexecute.full_databases()
1621
1687
 
@@ -1626,6 +1692,20 @@ def cli(
1626
1692
 
1627
1693
  sys.exit(0)
1628
1694
 
1695
+ if ping_database:
1696
+ try:
1697
+ list(pgcli.pgexecute.run("SELECT 1"))
1698
+ except Exception:
1699
+ click.secho(
1700
+ "Could not connect to the database. Please check that the database is running.",
1701
+ err=True,
1702
+ fg="red",
1703
+ )
1704
+ sys.exit(1)
1705
+ else:
1706
+ click.echo("PONG")
1707
+ sys.exit(0)
1708
+
1629
1709
  pgcli.logger.debug(
1630
1710
  "Launch Params: \n" "\tdatabase: %r" "\tuser: %r" "\thost: %r" "\tport: %r",
1631
1711
  database,
@@ -1808,6 +1888,7 @@ def format_output(title, cur, headers, status, settings, explain_mode=False):
1808
1888
  "missing_value": settings.missingval,
1809
1889
  "integer_format": settings.dcmlfmt,
1810
1890
  "float_format": settings.floatfmt,
1891
+ "column_date_formats": settings.column_date_formats,
1811
1892
  "preprocessors": (format_numbers, format_arrays),
1812
1893
  "disable_numparse": True,
1813
1894
  "preserve_whitespace": True,
@@ -1817,6 +1898,9 @@ def format_output(title, cur, headers, status, settings, explain_mode=False):
1817
1898
  if not settings.floatfmt:
1818
1899
  output_kwargs["preprocessors"] = (align_decimals,)
1819
1900
 
1901
+ if settings.column_date_formats:
1902
+ output_kwargs["preprocessors"] += (format_timestamps,)
1903
+
1820
1904
  if table_format == "csv":
1821
1905
  # The default CSV dialect is "excel" which is not handling newline values correctly
1822
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"
@@ -63,10 +63,17 @@ normalize_ref = lambda ref: ref if ref[0] == '"' else '"' + ref.lower() + '"'
63
63
 
64
64
 
65
65
  def generate_alias(tbl, alias_map=None):
66
- """Generate a table alias, consisting of all upper-case letters in
67
- the table name, or, if there are no upper-case letters, the first letter +
68
- all letters preceded by _
69
- param tbl - unescaped name of the table to alias
66
+ """Generate a table alias.
67
+
68
+ Given a table name will return an alias for that table using the first of
69
+ the following options there's a match for.
70
+
71
+ 1. The predefined alias for table defined in the alias_map.
72
+ 2. All upper-case letters in the table name.
73
+ 3. The first letter of the table name and all letters preceded by _
74
+
75
+ :param tbl: unescaped name of the table to alias
76
+ :param alias_map: optional mapping of predefined table aliases
70
77
  """
71
78
  if alias_map and tbl in alias_map:
72
79
  return alias_map[tbl]
@@ -528,7 +535,7 @@ class PGCompleter(Completer):
528
535
  scoped_cols = self.populate_scoped_cols(tables, suggestion.local_tables)
529
536
 
530
537
  def make_cand(name, ref):
531
- synonyms = (name, generate_alias(self.case(name)))
538
+ synonyms = (name, generate_alias(self.case(name), alias_map=self.alias_map))
532
539
  return Candidate(qualify(name, ref), 0, "column", synonyms)
533
540
 
534
541
  def flat_cols():
@@ -601,7 +608,7 @@ class PGCompleter(Completer):
601
608
  tbl = self.case(tbl)
602
609
  tbls = {normalize_ref(t.ref) for t in tbls}
603
610
  if self.generate_aliases:
604
- tbl = generate_alias(self.unescape_name(tbl))
611
+ tbl = generate_alias(self.unescape_name(tbl), alias_map=self.alias_map)
605
612
  if normalize_ref(tbl) not in tbls:
606
613
  return tbl
607
614
  elif tbl[0] == '"':
@@ -644,7 +651,7 @@ class PGCompleter(Completer):
644
651
  join = "{0} ON {0}.{1} = {2}.{3}".format(
645
652
  c(left.tbl), c(left.col), rtbl.ref, c(right.col)
646
653
  )
647
- alias = generate_alias(self.case(left.tbl))
654
+ alias = generate_alias(self.case(left.tbl), alias_map=self.alias_map)
648
655
  synonyms = [
649
656
  join,
650
657
  "{0} ON {0}.{1} = {2}.{3}".format(
@@ -845,7 +852,7 @@ class PGCompleter(Completer):
845
852
  cased_tbl = self.case(tbl.name)
846
853
  if do_alias:
847
854
  alias = self.alias(cased_tbl, suggestion.table_refs)
848
- synonyms = (cased_tbl, generate_alias(cased_tbl))
855
+ synonyms = (cased_tbl, generate_alias(cased_tbl, alias_map=self.alias_map))
849
856
  maybe_alias = (" " + alias) if do_alias else ""
850
857
  maybe_schema = (self.case(tbl.schema) + ".") if tbl.schema else ""
851
858
  suffix = self._arg_list_cache[arg_mode][tbl.meta] if arg_mode else ""
@@ -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,27 +1,27 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pgcli
3
- Version: 4.1.0
3
+ Version: 4.3.0
4
4
  Summary: CLI for Postgres Database. With auto-completion and syntax highlighting.
5
- Home-page: http://pgcli.com
6
- Author: Pgcli Core Team
7
- Author-email: pgcli-dev@googlegroups.com
5
+ Author-email: Pgcli Core Team <pgcli-dev@googlegroups.com>
8
6
  License: BSD
7
+ Project-URL: Homepage, https://pgcli.com
9
8
  Classifier: Intended Audience :: Developers
10
9
  Classifier: License :: OSI Approved :: BSD License
11
10
  Classifier: Operating System :: Unix
12
11
  Classifier: Programming Language :: Python
13
12
  Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.8
15
13
  Classifier: Programming Language :: Python :: 3.9
16
14
  Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
18
16
  Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
19
18
  Classifier: Programming Language :: SQL
20
19
  Classifier: Topic :: Database
21
20
  Classifier: Topic :: Database :: Front-Ends
22
21
  Classifier: Topic :: Software Development
23
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
- Requires-Python: >=3.8
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/x-rst
25
25
  License-File: LICENSE.txt
26
26
  License-File: AUTHORS
27
27
  Requires-Dist: pgspecial>=2.0.0
@@ -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.2.1
36
- Requires-Dist: setproctitle>=1.1.9
35
+ Requires-Dist: cli_helpers[styles]>=2.4.0
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
  ---------------------
@@ -220,7 +222,7 @@ Alternatively, you can install ``pgcli`` as a python package using a package
220
222
  manager called called ``pip``. You will need postgres installed on your system
221
223
  for this to work.
222
224
 
223
- In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installing.html.
225
+ In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installation/
224
226
 
225
227
  ::
226
228
 
@@ -250,7 +252,7 @@ If pip is not installed check if easy_install is available on the system.
250
252
  Linux:
251
253
  ======
252
254
 
253
- In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installing.html.
255
+ In depth getting started guide for ``pip`` - https://pip.pypa.io/en/latest/installation/
254
256
 
255
257
  Check if pip is already available in your system.
256
258
 
@@ -393,7 +395,10 @@ choice:
393
395
 
394
396
  In [3]: my_result = _
395
397
 
396
- Pgcli dropped support for Python<3.8 as of 4.0.0. If you need it, install ``pgcli <= 4.0.0``.
398
+ Pgcli dropped support for:
399
+
400
+ * Python<3.8 as of 4.0.0.
401
+ * Python<3.9 as of 4.2.0.
397
402
 
398
403
  Thanks:
399
404
  -------
@@ -4,7 +4,6 @@ MANIFEST.in
4
4
  README.rst
5
5
  changelog.rst
6
6
  pyproject.toml
7
- setup.py
8
7
  pgcli/__init__.py
9
8
  pgcli/__main__.py
10
9
  pgcli/auth.py
@@ -4,12 +4,15 @@ Pygments>=2.0
4
4
  prompt_toolkit<4.0.0,>=2.0.6
5
5
  sqlparse<0.6,>=0.3.0
6
6
  configobj>=5.0.6
7
- cli_helpers[styles]>=2.2.1
8
- setproctitle>=1.1.9
7
+ cli_helpers[styles]>=2.4.0
8
+ tzlocal>=5.2
9
9
 
10
10
  [:sys_platform != "win32"]
11
11
  psycopg>=3.0.14
12
12
 
13
+ [:sys_platform != "win32" and "CYGWIN" not in sys_platform]
14
+ setproctitle>=1.1.9
15
+
13
16
  [:sys_platform == "win32"]
14
17
  psycopg-binary>=3.0.14
15
18
 
@@ -0,0 +1,94 @@
1
+ [project]
2
+ name = "pgcli"
3
+ authors = [{ name = "Pgcli Core Team", email = "pgcli-dev@googlegroups.com" }]
4
+ license = { text = "BSD" }
5
+ description = "CLI for Postgres Database. With auto-completion and syntax highlighting."
6
+ readme = "README.rst"
7
+ classifiers = [
8
+ "Intended Audience :: Developers",
9
+ "License :: OSI Approved :: BSD License",
10
+ "Operating System :: Unix",
11
+ "Programming Language :: Python",
12
+ "Programming Language :: Python :: 3",
13
+ "Programming Language :: Python :: 3.9",
14
+ "Programming Language :: Python :: 3.10",
15
+ "Programming Language :: Python :: 3.11",
16
+ "Programming Language :: Python :: 3.12",
17
+ "Programming Language :: Python :: 3.13",
18
+ "Programming Language :: SQL",
19
+ "Topic :: Database",
20
+ "Topic :: Database :: Front-Ends",
21
+ "Topic :: Software Development",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ ]
24
+ urls = { Homepage = "https://pgcli.com" }
25
+ requires-python = ">=3.9"
26
+ dependencies = [
27
+ "pgspecial>=2.0.0",
28
+ "click >= 4.1",
29
+ "Pygments>=2.0", # Pygments has to be Capitalcased. WTF?
30
+ # We still need to use pt-2 unless pt-3 released on Fedora32
31
+ # see: https://github.com/dbcli/pgcli/pull/1197
32
+ "prompt_toolkit>=2.0.6,<4.0.0",
33
+ "psycopg >= 3.0.14; sys_platform != 'win32'",
34
+ "psycopg-binary >= 3.0.14; sys_platform == 'win32'",
35
+ "sqlparse >=0.3.0,<0.6",
36
+ "configobj >= 5.0.6",
37
+ "cli_helpers[styles] >= 2.4.0",
38
+ # setproctitle is used to mask the password when running `ps` in command line.
39
+ # But this is not necessary in Windows since the password is never shown in the
40
+ # task manager. Also setproctitle is a hard dependency to install in Windows,
41
+ # so we'll only install it if we're not in Windows.
42
+ "setproctitle >= 1.1.9; sys_platform != 'win32' and 'CYGWIN' not in sys_platform",
43
+ "tzlocal >= 5.2",
44
+ ]
45
+ dynamic = ["version"]
46
+
47
+
48
+ [project.scripts]
49
+ pgcli = "pgcli.main:cli"
50
+
51
+ [project.optional-dependencies]
52
+ keyring = ["keyring >= 12.2.0"]
53
+ sshtunnel = ["sshtunnel >= 0.4.0"]
54
+
55
+ [build-system]
56
+ requires = ["setuptools>=61.2"]
57
+ build-backend = "setuptools.build_meta"
58
+
59
+ [tool.setuptools]
60
+ include-package-data = false
61
+
62
+ [tool.setuptools.dynamic]
63
+ version = { attr = "pgcli.__version__" }
64
+
65
+ [tool.setuptools.packages]
66
+ find = { namespaces = false }
67
+
68
+ [tool.setuptools.package-data]
69
+ pgcli = [
70
+ "pgclirc",
71
+ "packages/pgliterals/pgliterals.json",
72
+ ]
73
+
74
+ [tool.black]
75
+ line-length = 88
76
+ target-version = ['py38']
77
+ include = '\.pyi?$'
78
+ exclude = '''
79
+ /(
80
+ \.eggs
81
+ | \.git
82
+ | \.hg
83
+ | \.mypy_cache
84
+ | \.tox
85
+ | \.venv
86
+ | \.cache
87
+ | \.pytest_cache
88
+ | _build
89
+ | buck-out
90
+ | build
91
+ | dist
92
+ | tests/data
93
+ )/
94
+ '''
@@ -51,6 +51,10 @@ Feature: run the cli,
51
51
  When we list databases
52
52
  then we see list of databases
53
53
 
54
+ Scenario: ping databases
55
+ When we ping the database
56
+ then we get a pong response
57
+
54
58
  Scenario: run the cli with --username
55
59
  When we launch dbcli using --username
56
60
  and we send "\?" command
@@ -26,6 +26,19 @@ def step_see_list_databases(context):
26
26
  context.cmd_output = None
27
27
 
28
28
 
29
+ @when("we ping the database")
30
+ def step_ping_database(context):
31
+ cmd = ["pgcli", "--ping"]
32
+ context.cmd_output = subprocess.check_output(cmd, cwd=context.package_root)
33
+
34
+
35
+ @then("we get a pong response")
36
+ def step_get_pong_response(context):
37
+ # exit code 0 is implied by the presence of cmd_output here, which
38
+ # is only set on a successful run.
39
+ assert context.cmd_output.strip() == b"PONG", f"Output was {context.cmd_output}"
40
+
41
+
29
42
  @when("we run dbcli")
30
43
  def step_run_cli(context):
31
44
  wrappers.run_cli(context)
@@ -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
@@ -1,5 +1,7 @@
1
+ import json
1
2
  import pytest
2
3
  from pgcli import pgcompleter
4
+ import tempfile
3
5
 
4
6
 
5
7
  def test_load_alias_map_file_missing_file():
@@ -47,12 +49,34 @@ def test_generate_alias_uses_first_char_and_every_preceded_by_underscore(
47
49
  "table_name, alias_map, alias",
48
50
  [
49
51
  ("some_table", {"some_table": "my_alias"}, "my_alias"),
52
+ pytest.param(
53
+ "some_other_table", {"some_table": "my_alias"}, "sot", id="no_match_in_map"
54
+ ),
50
55
  ],
51
56
  )
52
57
  def test_generate_alias_can_use_alias_map(table_name, alias_map, alias):
53
58
  assert pgcompleter.generate_alias(table_name, alias_map) == alias
54
59
 
55
60
 
61
+ @pytest.mark.parametrize(
62
+ "table_name, alias_map, alias",
63
+ [
64
+ ("some_table", {"some_table": "my_alias"}, "my_alias"),
65
+ ],
66
+ )
67
+ def test_pgcompleter_alias_uses_configured_alias_map(table_name, alias_map, alias):
68
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as alias_map_file:
69
+ alias_map_file.write(json.dumps(alias_map))
70
+ alias_map_file.seek(0)
71
+ completer = pgcompleter.PGCompleter(
72
+ settings={
73
+ "generate_aliases": True,
74
+ "alias_map_file": alias_map_file.name,
75
+ }
76
+ )
77
+ assert completer.alias(table_name, []) == alias
78
+
79
+
56
80
  @pytest.mark.parametrize(
57
81
  "table_name, alias_map, alias",
58
82
  [
@@ -1 +0,0 @@
1
- __version__ = "4.1.0"
@@ -1 +0,0 @@
1
- http://github.com/psycopg/repo/tarball/master#egg=psycopg-3.0.10
@@ -1,21 +0,0 @@
1
- [tool.black]
2
- line-length = 88
3
- target-version = ['py38']
4
- include = '\.pyi?$'
5
- exclude = '''
6
- /(
7
- \.eggs
8
- | \.git
9
- | \.hg
10
- | \.mypy_cache
11
- | \.tox
12
- | \.venv
13
- | \.cache
14
- | \.pytest_cache
15
- | _build
16
- | buck-out
17
- | build
18
- | dist
19
- | tests/data
20
- )/
21
- '''
pgcli-4.1.0/setup.py DELETED
@@ -1,71 +0,0 @@
1
- import platform
2
- from setuptools import setup, find_packages
3
-
4
- from pgcli import __version__
5
-
6
- description = "CLI for Postgres Database. With auto-completion and syntax highlighting."
7
-
8
- install_requirements = [
9
- "pgspecial>=2.0.0",
10
- "click >= 4.1",
11
- "Pygments>=2.0", # Pygments has to be Capitalcased. WTF?
12
- # We still need to use pt-2 unless pt-3 released on Fedora32
13
- # see: https://github.com/dbcli/pgcli/pull/1197
14
- "prompt_toolkit>=2.0.6,<4.0.0",
15
- "psycopg >= 3.0.14; sys_platform != 'win32'",
16
- "psycopg-binary >= 3.0.14; sys_platform == 'win32'",
17
- "sqlparse >=0.3.0,<0.6",
18
- "configobj >= 5.0.6",
19
- "cli_helpers[styles] >= 2.2.1",
20
- ]
21
-
22
-
23
- # setproctitle is used to mask the password when running `ps` in command line.
24
- # But this is not necessary in Windows since the password is never shown in the
25
- # task manager. Also setproctitle is a hard dependency to install in Windows,
26
- # so we'll only install it if we're not in Windows.
27
- if platform.system() != "Windows" and not platform.system().startswith("CYGWIN"):
28
- install_requirements.append("setproctitle >= 1.1.9")
29
-
30
- setup(
31
- name="pgcli",
32
- author="Pgcli Core Team",
33
- author_email="pgcli-dev@googlegroups.com",
34
- version=__version__,
35
- license="BSD",
36
- url="http://pgcli.com",
37
- packages=find_packages(),
38
- package_data={"pgcli": ["pgclirc", "packages/pgliterals/pgliterals.json"]},
39
- description=description,
40
- long_description=open("README.rst").read(),
41
- install_requires=install_requirements,
42
- dependency_links=[
43
- "http://github.com/psycopg/repo/tarball/master#egg=psycopg-3.0.10"
44
- ],
45
- extras_require={
46
- "keyring": ["keyring >= 12.2.0"],
47
- "sshtunnel": ["sshtunnel >= 0.4.0"],
48
- },
49
- python_requires=">=3.8",
50
- entry_points="""
51
- [console_scripts]
52
- pgcli=pgcli.main:cli
53
- """,
54
- classifiers=[
55
- "Intended Audience :: Developers",
56
- "License :: OSI Approved :: BSD License",
57
- "Operating System :: Unix",
58
- "Programming Language :: Python",
59
- "Programming Language :: Python :: 3",
60
- "Programming Language :: Python :: 3.8",
61
- "Programming Language :: Python :: 3.9",
62
- "Programming Language :: Python :: 3.10",
63
- "Programming Language :: Python :: 3.11",
64
- "Programming Language :: Python :: 3.12",
65
- "Programming Language :: SQL",
66
- "Topic :: Database",
67
- "Topic :: Database :: Front-Ends",
68
- "Topic :: Software Development",
69
- "Topic :: Software Development :: Libraries :: Python Modules",
70
- ],
71
- )
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