Skip to content

命令行美化(pgcli) ​

pgcli 是一个基于 Python 的 PostgreSQL 交互式命令行客户端(Interactive Terminal Client),在保留 psql 使用习惯的同时,补上了 psql 缺失的语法高亮、智能补全与多行编辑。本节将介绍 pgcli 与 psql 的差异、安装方式、配置文件、补全能力与局限。

前置知识

阅读本节前,建议先了解:Navicat / DataGrip

基础概念 ​

psql 是官方客户端,功能最全、行为最稳定,但它的交互体验停留在「纯文本终端」时代:没有语法着色,补全依赖手写查询,长 SQL 编辑不便。

pgcli 的思路是只重做交互层,不动协议层:

  • 底层仍通过 libpq(Python 侧的 psycopg)连接 PostgreSQL,行为与 psql 一致
  • 上层用 Python 的提示工具包(prompt_toolkit)重写输入区,实现实时补全与语法高亮
  • 元命令(Meta-Command)尽可能兼容 psql,\d、\dt、\x、\timing 等仍可用

理解这一点很重要:pgcli 不是 psql 的替代品,而是 psql 的「编辑器增强版」。写脚本、做批处理仍应使用 psql;交互式探索、编写复杂查询时 pgcli 更舒服。

术语英文名说明
语法高亮Syntax Highlighting按词法给 SQL 关键字、字符串、标识符着色
智能补全Smart Completion基于数据库元数据补全表名、列名、函数、关键字
多行模式Multi-line Mode允许回车换行而非立即执行,便于编辑长 SQL
模糊匹配Fuzzy Matching输入片段即可匹配,如 usod 匹配 user_orders
提示工具包prompt_toolkitpgcli 依赖的终端交互库
包装器Wrapperpgcli 对 psql 元命令的兼容实现

安装与配置 ​

安装方式对比 ​

方式命令隔离性适用场景
pipxpipx install pgcli高(独立虚拟环境)推荐的通用方式
pippip install --user pgcli低(污染用户环境)已有虚拟环境管理习惯
Homebrewbrew install pgcli中(brew 托管)macOS 用户最省事
aptsudo apt install pgcli中Debian/Ubuntu 快速安装
Dockerdocker run ... pgcli完全隔离不想在宿主机装 Python 依赖
bash
# ── 推荐:pipx(Python 3.9+)──
python3 -m pip install --user pipx
python3 -m pipx ensurepath
pipx install pgcli

# 升级
pipx upgrade pgcli

# ── macOS:Homebrew ──
brew install pgcli

# ── Debian / Ubuntu ──
sudo apt update && sudo apt install -y pgcli

# ── Windows:scoop ──
scoop install pgcli
bash
# 验证安装:查看版本与依赖的驱动
pgcli --version
# pgcli 4.x
# psycopg 3.x

# 确认 pgcli 找到了 psql 的元命令后端(部分功能依赖本地 psql)
which psql
psql --version

连接方式 ​

pgcli 的连接参数与 psql 高度一致,支持短选项、长选项、DSN 与环境变量:

bash
# 短选项
pgcli -h 127.0.0.1 -p 5432 -U app_user -d demo

# 长选项
pgcli --host=127.0.0.1 --port=5432 --user=app_user --dbname=demo

# DSN(同 libpq 格式,可直接粘贴 psql 的连接串)
pgcli "postgresql://app_user:secret@127.0.0.1:5432/demo?sslmode=require"

# 只传库名,其余从环境变量读取
PGHOST=127.0.0.1 PGUSER=app_user PGPASSWORD=secret pgcli demo

# 复用 psql 的服务定义(~/.pg_service.conf)
pgcli service=demodb
text
# ~/.pg_service.conf(psql 与 pgcli 共用)
[demodb]
host=127.0.0.1
port=5432
dbname=demo
user=app_user
sslmode=require

配置文件 ​

pgcli 的主配置文件位于 ~/.config/pgcli/config(Windows 为 %USERPROFILE%\AppData\Local\pgcli\config):

ini
# ~/.config/pgcli/config
[main]
# 多行模式:safe 表示仅当语句以分号结尾才执行
multi_line_mode = safe

# 关键字大小写:upper / lower / auto
keyword_casing = upper

# 是否启用语法高亮
highlight = True

# 补全时是否显示表名的 schema 前缀
qualify_columns = always

# 智能补全(基于元数据)
smart_completion = True

# 模糊匹配:usod 可匹配 user_orders
fuzzy_search = True

# 是否显示执行耗时(等价于 \timing on)
timing = True

# 表名后缀过滤,排查线上库时很有用
# table_format = psql

# 结果行数上限(防止误查大表把终端刷爆)
row_limit = 1000

# 历史文件
history_file = ~/.config/pgcli/history
ini
# 亦可直接指定「启动时自动执行的命令」,等价 psql 的 ~/.psqlrc
# ~/.config/pgcli/config 中的 [main] 段落不支持 SQL,故用别名方式实现:
bash
# 在 ~/.bashrc / ~/.zshrc 中定义别名,实现「带默认上下文启动」
alias pgl='pgcli -h 127.0.0.1 -p 5432 -U app_user -d demo'
alias pgl-prod='pgcli -h 10.0.0.10 -U read_only -d demo_prod'

# 让 pgcli 读取 psql 风格的 rc 文件(部分版本支持 --rcfile)
pgcli --rcfile ~/.psqlrc -d demo

详细说明 ​

pgcli 与 psql 的能力对照 ​

能力psqlpgcli
语法高亮无有(实时着色)
智能补全(表/列/函数)有限(\d 前后 Tab)有(元数据驱动)
模糊匹配补全无有
多行编辑有(编辑缓冲区)有(更接近现代编辑器)
\d / \dt / \l 等元命令原生兼容实现(绝大多数可用)
\copy原生支持
\e 外部编辑器支持支持(EDITOR 环境变量)
\watch支持兼容(版本依赖)
\gexec支持支持
\set 变量原生部分兼容
-c / -f 非交互模式原生支持
输出格式(\pset)最全(csv/html/latex 等)常用格式
环境依赖仅 libpq需要 Python 运行时
启动速度极快(毫秒级)较慢(数百毫秒)
脚本可靠性最高建议改用 psql

结论:交互式探索用 pgcli,生产脚本用 psql。二者可共存,别名互不冲突。

补全与高亮细节 ​

pgcli 的补全是上下文感知的:

  1. 位置感知:在 SELECT 后补全列名与函数;在 FROM 后补全表名与视图;在 JOIN 后优先补全可连接的表
  2. 元数据驱动:补全列表来自数据库系统目录(System Catalog),新加的表无需重启即可出现
  3. 模糊匹配:usod → user_order_detail,coem → customer_email
  4. 多候选切换:Tab 触发补全,Shift + Tab 反向切换候选,Esc 关闭候选列表
  5. 别名感知:SELECT u. 后只补全 u 别名对应表的列
sql
-- 补全示例:输入 `sele` + Tab 自动补全为 SELECT
-- 输入 `SELECT * FROM usod` + Tab,候选出现 user_order_detail
sele * frm user_order_detail wt uod
jion user_orders uo on uo.id = uod.order_id
wt uod.created_at > now() - intervl '7 days';
text
# 补全候选列表示意(按 Tab 后)
> SELECT * FROM user_ord|          ← 光标位置
  user_orders
  user_order_detail
  user_order_stats

pgcli 的高亮规则:

元素默认颜色说明
SQL 关键字青色/加粗SELECT、FROM、WHERE 等
字符串字面量绿色'2026-01-01'
数字黄色100、3.14
内置函数品红now()、count()
表名/列名白色普通标识符
错误提示红色语法或执行错误

多行模式与执行控制 ​

pgcli 提供三档多行模式:

模式行为建议
off回车即执行(同 psql 单行)习惯 psql 者
safe仅当语句以 ; 结尾才执行,否则换行推荐默认
always回车始终换行,用 Esc + Enter 执行编写长 SQL
text
# safe 模式下的交互示意(> 提示符)
demo> SELECT id, email

demo> FROM users

demo> WHERE status = 'active'    ← 尚未输入分号,继续换行
demo> ;

 id |        email
----+---------------------
  1 | alice@example.com
(1 row)
text
# always 模式下用 Esc 再回车执行
demo> SELECT count(*) FROM orders
demo> WHERE created_at >= now() - interval '1 day'
demo> [Esc][Enter]              ← 触发执行

 count
-------
  1842
(1 row)

常用操作与快捷键 ​

快捷键功能
Tab触发补全 / 切换到下一个候选
Shift + Tab切换到上一个候选
Esc 然后 Enter在 always 模式下执行
Ctrl + R反向搜索历史
Ctrl + C中止当前输入或查询
Ctrl + D退出 pgcli
F2切换多行模式
F3切换补全开关
F4切换语法高亮
Ctrl + Space强制显示补全候选

pgcli 也实现了大量 psql 元命令:

sql
-- 服务端信息
\conninfo                    -- 当前连接详情(含 SSL 状态)
\l                           -- 列出数据库
\dt                          -- 列出表
\dt+                         -- 列出表(含大小与描述)
\d users                     -- 查看表结构
\dn                          -- 列出 schema
\du                          -- 列出角色
\df                          -- 列出函数
\dx                          -- 列出扩展
\dp users                    -- 查看表权限
sql
-- 输出与执行控制
\timing on                   -- 显示执行耗时
\x auto                      -- 宽结果自动转纵向显示
\o /tmp/result.txt           -- 后续结果写入文件
\i ./migrations/001_init.sql -- 执行外部 SQL 文件
\e                           -- 用 $EDITOR 打开编辑器编写 SQL
\pset pager off              -- 关闭分页器,便于复制结果
\q                           -- 退出

实战示例 ​

场景一:用补全快速写一条多表查询 ​

目标:查询近 7 天各渠道的订单金额与退款率。

sql
-- 第 1 步:先用 \dt 确认表名(Tab 补全可省去手输)
\dt

-- 第 2 步:利用别名补全编写查询
SELECT o.channel,
       count(*)                                        AS order_cnt,
       sum(o.amount)                                   AS gmv,
       count(*) FILTER (WHERE o.status = 'refunded')   AS refund_cnt,
       round(
         100.0 * count(*) FILTER (WHERE o.status = 'refunded') / count(*),
         2
       )                                               AS refund_rate
FROM orders AS o
WHERE o.created_at >= now() - interval '7 days'
GROUP BY o.channel
ORDER BY gmv DESC;
text
# 输出示例(pgcli 会按列宽自动对齐)
 channel  | order_cnt |   gmv    | refund_cnt | refund_rate
----------+-----------+----------+------------+-------------
 app      |      8123 | 4213380  |         94 |        1.16
 web      |      4102 | 2188660  |         61 |        1.49
 miniapp  |      2308 |  962450  |         38 |        1.65
 offline  |       412 |  386200  |          7 |        1.70
(4 rows)

Time: 0.187s

场景二:用 pgcli 做一次带 SSL 校验的连通性检查 ​

bash
# 在 CI 或跳板机上,用 pgcli 快速确认「能连、且走的是 SSL」
pgcli "postgresql://app_user:secret@db.example.com:5432/demo?sslmode=verify-full&sslrootcert=/etc/pki/ca.crt" \
  -c "\conninfo"
text
# \conninfo 输出示例
You are connected to database "demo" as user "app_user" on host "db.example.com" (address "10.0.0.21") at port "5432".
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)

场景三:把 pgcli 用于日常巡检的包装脚本 ​

bash
#!/usr/bin/env bash
# inspect-pgcli.sh:交互巡检入口,避免每次都手输连接参数
set -euo pipefail

DB_URL="${DATABASE_URL:?请先设置 DATABASE_URL}"

exec pgcli "${DB_URL}" \
  --row-limit 500 \
  --timing
bash
# 使用方式
export DATABASE_URL="postgresql://app_user:secret@127.0.0.1:5432/demo"
chmod +x inspect-pgcli.sh
./inspect-pgcli.sh

# 进入后常用三连
#   \conninfo   确认连接与 SSL
#   \dt+        看表大小,找出异常膨胀的表
#   \timing on  开启计时后跑排查查询

注意事项 ​

  • 不要用 pgcli 跑生产批处理:pgcli 的启动开销与补全元数据查询会拖慢脚本;且其元命令实现是「兼容层」而非原生,边界行为可能与 psql 有差异。批处理请用 psql -f。
  • 补全会连库查元数据:首次补全可能触发系统目录查询,在表特别多(上万张)的库上会有可感知延迟。可用 fuzzy_search = False 或关闭补全(F3)缓解。
  • row_limit 是保护伞:默认限制返回行数,避免误查大表刷爆终端。做精确统计时注意别被截断——需要全量结果时应改用 \o 或 psql -c。
  • Python 环境隔离:用 pip install pgcli 而非 pipx 时,容易与系统 Python 包冲突(尤其是 psycopg 版本),优先用 pipx。
  • 版本对齐:pgcli 依赖的 psycopg 需支持 PostgreSQL 18 的协议与认证(如 scram-sha-256 为默认时的握手)。连接报认证错误时先升级 pgcli 与驱动。
  • 密码安全:不要在命令行直接写 -W 之外的口令,也不要把带密码的 DSN 写进 shell 历史。使用 ~/.pgpass(权限 600)或 PGPASSWORD 环境变量。
bash
# 正确:使用 .pgpass,避免密码进入 shell 历史
# ~/.pgpass 内容格式:hostname:port:database:username:password
echo "127.0.0.1:5432:demo:app_user:secret" >> ~/.pgpass
chmod 600 ~/.pgpass

# 之后连接不再需要输入密码
pgcli -h 127.0.0.1 -U app_user -d demo
  • 历史文件可能含敏感 SQL:pgcli 的历史记录默认落盘,若查询中含个人信息或密钥,应定期清理或关闭历史(history_file 指向临时目录)。

最佳实践 ​

  • psql 与 pgcli 双持:日常交互用 pgcli,脚本与排障用 psql。两者共享 ~/.pgpass、~/.pg_service.conf、环境变量,无需重复配置。
  • 把连接固化到 service 文件:用 ~/.pg_service.conf + pgcli service=xxx,避免在命令历史里散落主机名与账号。
  • 开 timing 与 \x auto:前者让性能问题一眼可见,后者让宽表结果更可读。
  • 用 F3/F4 动态开关:在大库上感到卡顿时临时关补全,需要时再开,比改配置重启更快。
  • 把常用巡检 SQL 存成文件:用 \i 载入,比每次手敲更可靠,也便于纳入 Git。
  • 不迷信美化:高亮与补全提升的是输入效率,不改变 SQL 语义。执行计划、索引、锁的分析仍需回到 EXPLAIN 与服务端视图。

下一节

继续学习:postgres 用户与密码设置

参考链接 ​