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.conf在pg_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 命令行工具的不一致性让你有点抓狂(不同的标志、psql、pg_dump、pg_restore 之间不兼容的语法……),我也为此构建了一个 bash 包装器:PG Lord of the Ring。一个工具统治它们全部。