pg_service.conf:你团队遗忘的魔法

4 阅读4分钟

pg_service.conf:你团队遗忘的魔法

**摘要:**本文介绍 pg_service.conf,这是一个简单的 INI 格式配置文件,允许开发者为 PostgreSQL 定义命名的连接配置文件,无需记忆复杂的连接字符串,并通过配置文件中的统一服务别名实现无缝的环境切换。

原文链接


说实话,我是个老派玩家。我的 IDE 是 vim。我的 PostgreSQL 客户端是 psql。我已经用了快 20 年了,仍然认为它是最好的 PostgreSQL 客户端。我可能有偏见。

当我加入一个新团队时,我注意到一件事:没人用 psql。大家都通过 IDE 连接。公平地说,IDE 确实保存了连接配置文件。点击就进去了,我理解。

但我用的是 vim。所以我需要别的东西。

这就是 pg_service.conf

连接字符串的问题

连接 PostgreSQL 时,你需要记住一堆东西:主机、端口、数据库名称和用户。这是四个容易出错的地方。更有趣的是:PostgreSQL 中的数据库名称很少是同事们谈论时用的名字。他们说"prod"。实际的数据库叫 mycompany_production_v2。祝你好运能记住这个。

pg_service.conf 是什么?

它是一个简单的 INI 格式文件,你可以在其中定义命名的连接配置文件。像这样:

[prod]
host=db.mycompany.com
port=5432
dbname=mycompany_production_v2
user=laetitia
[staging]
host=db-staging.mycompany.com
port=5432
dbname=mycompany_staging
user=laetitia

就这样。现在连接时,你只需要:

psql service=prod

你用团队交流的方式来命名服务。不再需要人类名字和技术名字之间的 mental mapping。

文件放在哪里?

两个选择:

  • 每用户:~/.pg_service.conf(或 $PGSERVICEFILE 指向的位置)
  • 系统级:pg_service.confpg_config --sysconfdir 返回的目录中

如果同一服务名同时存在于两个文件中,用户文件优先于系统级文件。

如果你被困在 Windows 上,而且在大公司里有时你没有选择,用户文件位于 %APPDATA%\postgresql\.pg_service.conf。它的作用方式相同。

每个环境一个文件

这里就变得非常有趣了。你可以每个环境一个文件。技巧:在每个文件中使用相同的服务名称。

我的 ~/.pg_service_prod.conf 和我的 ~/.pg_service_staging.conf 都有一个 [db1]、一个 [db2]、一个 [reporting]。别名与我团队对这些数据库的称呼相匹配。只有连接细节不同。

所以 psql service=db1 始终意味着同样的事情。你连接到哪个 db1 取决于加载的是哪个文件。不需要编辑。不会出错。

我更近一步。我们通过 AWS 连接到数据库,这意味着需要身份验证、导出凭证,然后连接。我把这一切包装成一个脚本,接受两个参数:环境和数据库别名。

./connect.sh staging db1

脚本处理 AWS 身份验证,将 PGSERVICEFILE 设置到正确的文件,然后调用 psql service=db1。一个命令。搞定。而且因为别名在文件间是一致的,脚本保持简单。

密码怎么办?

不要把密码放在服务文件里。真的。

pg_service.conf 的最佳搭档是 .pgpass。它是另一个文件(Linux/Mac 上是 ~/.pgpass),你可以在其中存储密码,按主机、端口、数据库和用户匹配。PostgreSQL 自动读取它。文件必须有 0600 权限,否则 PostgreSQL 会拒绝使用它。

这两个文件一起给你无密码连接,而不会把任何敏感信息存储在可能不小心分享的文件中。

最佳用例:入职

将系统级的 pg_service.conf 放入你的版本控制。当新成员加入团队时,他们克隆仓库,将文件复制到正确位置,设置他们的 .pgpass,他们第一天就能连接到每个环境。

没有"嘿能把连接详情发给我吗"的 Slack 消息。没有复制粘贴错误。没有把错误的主机放在错误的脚本里。

还有一件事

我说 psql 是最好的 PostgreSQL 客户端。我维护了整个网站来证明这一点:psql-tips.org。如果你还不信,去看看。

如果 PostgreSQL 命令行工具的不一致性让你有点抓狂(不同的标志、psqlpg_dumppg_restore 之间不兼容的语法……),我也为此构建了一个 bash 包装器:PG Lord of the Ring。一个工具统治它们全部。