跳转至

Snowflake 连接器

Snowflake 通过 SQL API v2(/api/v2/statements)接入,认证用密钥对 JWT——不用驱动、不用 SDK、也没有口令。JWT 由你的 PKCS#8 私钥签出,有效期一小时,到期前会提前重签。

这个 API 是无状态的:每个请求各自带上 warehouse、database、schema 和 role,所以 USE 不会在语句之间保留。由 exec-snowflake 控制。

连接配置

datasources:
  snowflake:
    type: snowflake
    account: ${SNOWFLAKE_ACCOUNT}    # 完整账号标识,例如 ab12345.us-east-2.aws
    username: ${SNOWFLAKE_USER}
    warehouse: COMPUTE_WH
    role: SYSADMIN                   # 可选
    database: ANALYTICS              # 两段式表名的会话默认库
    schema: PUBLIC                   # 可选
    private_key_file: ~/.config/dosi/snowflake_key.p8   # PKCS#8 PEM
    private_key_file_pwd: ${SNOWFLAKE_KEY_PASSPHRASE}   # 私钥没加密就不用写

参数

类型 必填 默认 说明
type string snowflake
account string 完整账号标识;端点会拼成 https://<account>.snowflakecomputing.com,JWT 用其中的 locator 部分。
username string 这把密钥所属的账号。
private_key_file path PKCS#8 PEM,可以是 PBES2 加密的。
private_key_file_pwd string 加密私钥的口令。${VAR} 规则与 password 相同,明文同样会告警。
warehouse string 每个请求都会带上。
role string 每个请求都会带上。
database string 会话默认库,两段式 schema.table 名靠它解析。
schema string 会话默认 schema。
default bool false 连接配置

本连接器解析但不使用的键: password——这里没有口令认证,只有密钥对——以及 hostporturi(直接报错)、sslmodesslrootcertcatalogarrow_flight_portcompat_mode

认证

生成一对密钥,把公钥注册到 Snowflake 用户上,然后让 private_key_file: 指向私钥。JWT 的签发者和主体会自动从账号 locator、用户名和公钥的 SHA-256 指纹推导出来,不用再配置什么。

口令放环境变量里(private_key_file_pwd: ${VAR});写明文也能用,但会在 stderr 上告警。

已知限制

  • 累计窗口帧上不支持 CORR/COVAR_* Snowflake 会以 Cumulative window frame unsupported 拒绝,所以这类指标在这个方言下会被拒。
  • 整数上的窗口 AVG 返回 3 位定点小数,与其它引擎对同一个滑动平均给出的精确值对不上。
  • 暂不支持多分区结果——结果集非常大时会报 Snowflake returned a multi-partition result
  • 未加引号的标识符会以大写返回,所以输出里的列名大小写和 DuckDB、Postgres 家族不同。

日期会替你处理:这个 API 把 DATE 返回成距 epoch 的天数,解码器会转回 ISO 日期。

本地验证连接

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

认证有问题时会以 HTTP 401 加 Snowflake 自己的消息出现,从中能区分是公钥没注册还是账号标识写错了。

排错

报错 原因与处理
connection "x" (snowflake) needs account / needs user / needs private_key_file 三个必填键。注意消息里说的是 user,而配置里的键叫 username
connection "x": cannot read private_key_file <path>: <e> 路径或权限问题;这里的 ~ 不会由 shell 展开,失败时请写完整路径。
connection "x": bad encrypted key: <e> private_key_file_pwd 不对,或者私钥用的不是 PBES2 加密。
connection "x": bad key: <e> 不是 PKCS#8 PEM——PKCS#1(BEGIN RSA PRIVATE KEY)会落在这里,需要转换。
HTTP 401: <body> 公钥没注册到该用户,或者账号标识写错了。
Snowflake returned a multi-partition result; not supported yet 把查询缩小——加过滤条件或 LIMIT
bad Snowflake JSON: <e> 端点返回了意料之外的内容,通常是代理或故障页。

参考链接