跳转至

PostgreSQL 连接器

PostgreSQL 走 Postgres 线协议,底层用 postgres crate。每条查询先 prepare——权威的类型 OID 从这里来——再用 simple_query 以文本形式取值,这样 NUMERICSUM/AVG 的输出类型)不用引入十进制库也能精确归一。

会话固定为 SET TIME ZONE 'UTC',所以无论服务端 timezone 设成什么,TIMESTAMPTZ 都不带时区返回,时间粒度分桶也就能和其它引擎对齐。

连接走池化(r2d2,默认 8 条),按需建立。由 exec-postgres feature 控制。

连接配置

datasources:
  warehouse_pg:
    type: postgres
    host: pg.internal
    port: 5432
    username: dosi
    password: ${PG_PASSWORD}
    database: analytics
    schema: public          # 可选
    sslmode: prefer         # 见下面的 TLS

也可以写成一整串 DSN:

datasources:
  warehouse_pg:
    type: postgres
    uri: postgres://dosi:${PG_PASSWORD}@pg.internal:5432/analytics

参数

类型 必填 默认 说明
type string postgres
host string 是* *除非给了 uri:
port int 5432 驱动默认值。
username string
password string 尽量用 ${VAR};明文会在 stderr 上告警。
database string
schema string 固定 search_path
uri string 完整的 postgres:// DSN,libpq 关键字语法。它会取代 host/port/username/password/database 这几个离散键——只有一个例外:显式写的 sslmode: 仍然覆盖 DSN 里带的。
sslmode string prefer TLS
sslrootcert path CA 证书包,校验类模式必填。
default bool false 连接配置

本连接器解析但不使用的键: arrow_flight_portcompat_modeaccountrolewarehousecatalog

连接池大小不在配置里,它是进程级的:server 上用 --pool-sizeDOSI_POOL_SIZE,Python 绑定里是 pool_size=,其余情况是 8。

TLS

sslmode: 用 libpq 的词汇表,也用 libpq 的校验阶梯:

sslmode 是否加密 是否校验证书
disable
allowprefer (默认) 服务端支持就加密
require 只有同时写了 sslrootcert: 才校验(libpq 的历史兼容行为)
verify-ca 校验证书链,用 sslrootcert: 指定的 CA
verify-full 证书链主机名

两点值得知道。进入校验模式后,内置根证书库是被刻意关掉的——这条连接只信 sslrootcert: 里那个 CA,别的都不信。另外 verify-ca/verify-full 没配 sslrootcert: 会在构造阶段直接报错,而不是悄悄降级成不校验。

已知限制

  • 没有三参数 DATEDIFF PostgreSQL 没有 DATEDIFF(unit, start, end);用了它的指标在这个方言下会在编译期被拒,而不是返回一个略有出入的结果。改用日期算术(end - start)或 EXTRACT
  • 整数除法会截断,Postgres 家族都是如此。比率型指标由编译器算成真正的比值,但字段表达式里手写的整数除法仍然截断。
  • 文本排序取决于服务端的 collation,所以 ORDER BY 的结果可能和 C collation 的引擎(比如 Hologres 或 DuckDB)不一样。

本地验证连接

$ dosi query --model model.yaml \
    --metrics revenue --group-by orders.status --execute --connection warehouse_pg

配置不对时,报错会点明卡在哪一段:connection 类错误是根本没连上,auth 类是连上了但被拒,sql_rejected 是服务端对编译出的 SQL 的原话。

排错

报错 原因与处理
connection "x": bad url: <e> uri: 不是合法的 postgres:// DSN。
connection "x" (postgres) is missing required field "host" host:,或者给完整的 uri:
server rejected SQL (<code>): <message> Postgres 拒了编译出的语句;SQLSTATE 和文字都是服务端的。
connection "x": unknown sslmode "verify" 只能是 disableallowpreferrequireverify-caverify-full
connection "x": sslmode "verify-full" verifies the server certificate, which needs a CA bundle 补上 sslrootcert: /path/to/ca.pem
connection "x": sslrootcert "<path>" is not a PEM certificate 文件在,但不是 PEM——DER 格式的 .crt 会落在这里。
this build has no postgres executor (feature "exec-postgres" not enabled) 官方二进制自带;自己编译的要加 --features exec-postgres

参考链接