BigQuery 连接器¶
BigQuery 通过 jobs.query REST API 访问,
用服务账号认证 —— 不需要驱动,也不需要 SDK。用服务账号的私钥签一个短期断言,
换成 OAuth access token,token 会缓存起来,快过期时自动重新获取。
这个 API 每个请求都是独立的:默认数据集随每个请求一起发送,USE 不会在语句之间保留。
由 exec-bigquery 这个 feature 控制。
实验阶段
完整的对拍语料库已对真实项目跑通 —— 216 个用例全过,没有跳过任何一个, 另有一组冒烟测试覆盖各类型解码与多页结果。之所以仍标记为实验阶段而非预览: 它还没进每日 CI 矩阵,而且结果是按行返回的,走的不是列式读取。参见 连接器成熟度。
连接配置¶
datasources:
bigquery:
type: bigquery
project: ${BIGQUERY_PROJECT} # GCP 项目 ID(也可写 catalog:)
dataset: ${BIGQUERY_DATASET} # 默认数据集(也可写 database:)
credentials_path: ~/.gcp/service-account.json
location: US # 可选,例如 US / EU
billing_project_id: quota-project # 可选,默认取 project
字段名与 datus-bigquery adapter 保持一致,所以同一份 datasource 配置
可以同时给 datus-agent 和 Dosi 用。
参数¶
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
type |
string | 是 | — | bigquery |
project |
string | 是 | — | GCP 项目 ID。也可以写成 catalog:(Datus 对这一层的叫法),两种写法只能选一个。 |
dataset |
string | 否 | — | 默认数据集,这样 SQL 里只写表名也能解析。也可以写成 database:,同样只能选一个。 |
credentials_path |
path | 三者选一 | — | 服务账号 JSON 密钥文件的路径。 |
credentials_info |
string | 三者选一 | — | 服务账号 JSON 的内容本身。建议用 ${VAR} —— 规则和 password 一样,包括明文告警。 |
credentials_base64 |
string | 三者选一 | — | 同一份 JSON 的 base64 编码,适合会破坏换行的密钥管理系统。 |
location |
string | 否 | API 默认值 | 任务所在区域(US、EU、asia-northeast1 等)。如果数据集不在 API 的默认区域,这个必须填。 |
billing_project_id |
string | 否 | 取 project |
任务的计费项目,任务也在这个项目里创建。 |
default |
bool | 否 | false |
见连接配置。 |
这个连接器会解析但忽略的字段:host、port、username、password、
uri(直接报错)、schema(也会报错,原因见下)、sslmode、sslrootcert、
warehouse、role、arrow_flight_port、compat_mode。
认证¶
给服务账号创建一个密钥,然后让 credentials_path: 指向它:
$ gcloud iam service-accounts keys create ~/.gcp/service-account.json \
--iam-account=<name>@<project>.iam.gserviceaccount.com
这个账号需要在计费项目上有 bigquery.jobs.create 权限,以及对数据的读权限。
断言的签发者、受众和 scope 都从密钥文件里推导出来,不需要额外配置。
如果不想把密钥放在文件系统里,可以直接传内容:
三个凭据字段只能配一个。配了两个就意味着有两个候选密钥, 而默认挑一个正是"用错身份连上去"的由来。
不支持应用默认凭据(ADC)。 gcloud auth application-default login 写出来的文件是
authorized_user 类型,它需要 refresh_token 授权流程,而不是服务账号的 JWT 流程;
连接器会直接指出这一点,而不是让你后面撞上一个看不懂的签名错误。
两个项目,不是一个¶
billing_project_id 是任务运行和计费的地方,project 是表所在的地方。
两者经常相同,但服务账号常常只能在自己的项目里创建任务,却要读另一个项目的数据。
如果这两个搞反了,报的是创建任务时的权限错误,而不是找不到表:
已知限制¶
- 没有 schema 这一层。 BigQuery 的命名空间是 project → dataset,
dataset 底下没有更细的层级,所以写了
schema:会直接报错,而不是被悄悄忽略。 把数据集写进dataset:(或database:)。 - 只有行式路径。 结果以 JSON 返回,再由公共的归一化层转成 Arrow。
列式的 Storage Read API 还没有接入,它被归到了计划中的通用
exec-adbc通道里。 - DDL 里的
PRIMARY KEY和FOREIGN KEY必须声明成NOT ENFORCED, 而且 BigQuery 没有AUTO_INCREMENT、SERIAL、存储ENGINE或DISTRIBUTED BY子句 —— 如果你通过--execute跑初始化脚本,这几条会有影响。
时间和数值类型不用你操心。这个 API 报的是它的旧版类型名
(INTEGER、FLOAT、BOOLEAN,而不是你在 DDL 里写的 GoogleSQL 类型
INT64、FLOAT64、BOOL),TIMESTAMP 用科学计数法表示 epoch 秒,
DATETIME 和 TIME 的小数部分会补齐到微秒;这些都会被归一化成其他连接器
一致的形式。NUMERIC 和 BIGNUMERIC 里超出浮点精度的值会保留为精确的
十进制文本。
本地验证连接¶
$ dosi query --model model.yaml \
--metrics revenue --group-by orders.status --execute --connection bigquery
认证有问题时会看到 HTTP 401,或者 token 端点返回的错误, 里面带着 Google 自己的提示,足以区分"密钥被吊销"和"项目填错"。
排错¶
| 报错 | 原因与处理 |
|---|---|
connection "x" (bigquery) needs project |
填 project:(或 catalog:)。 |
connection "x" (bigquery) has no credentials |
credentials_path / credentials_info / credentials_base64 一个都没配。不会去找 ADC。 |
datasource "x" (bigquery) sets more than one of credentials_path, … |
只保留一个。 |
connection "x": credentials are of type "authorized_user", not "service_account" |
这是 gcloud auth application-default login 生成的 ADC 文件。请改用服务账号密钥。 |
connection "x": credentials are not valid JSON / lack client_email / lack private_key |
不是服务账号密钥文件,或者复制时被截断了。 |
connection "x": bad service-account private key |
private_key 字段不是 PKCS#8 PEM。Google 签发的密钥不会这样,出现这个说明 JSON 被改过。 |
datasource "x": credentials_info must be a string |
它被写成了嵌套的 YAML。请改用 ${VAR} 或 credentials_path。报错时不会回显该字段的值,密钥不会进日志。 |
datasource "x": bigquery has no schema level below a dataset |
去掉 schema:。 |
datasource "x": sets both "project" and "catalog"(或 "dataset"/"database") |
这两组互为别名,各保留一个。 |
token endpoint returned no access_token: <msg> |
时钟偏差超出了断言的有效窗口,或密钥已被禁用/删除,或服务账号没有 BigQuery scope。 |
Access Denied: … does not have bigquery.jobs.create permission |
billing_project_id(或 project)指向了一个该账号无法创建任务的项目。 |
Not found: Dataset <p>:<d> |
dataset 写错了,或者数据集在另一个 location。 |
BigQuery job did not finish within the poll budget |
查询超过了五分钟。请缩小范围。 |
bad BigQuery JSON: <e> |
端点返回了非预期内容,通常是代理或故障页面。 |
参考链接¶
- 官方站点:https://cloud.google.com/bigquery
- API:
jobs.query与服务账号授权 - 同样是无状态云 API 的连接器:Snowflake、Databricks
- 连接配置