本文以 Google Sheets API v4 为例,介绍如何通过 REST API 数据源 与 离线单表同步任务,将 Google Sheet 中的表格数据加载到 DataBuddy Catalog 的目标表(Iceberg 原生表)中。
文中给出的参数可直接替换为您的表格信息。其他通过 REST 接口提供数据的 SaaS 系统,也可参考本流程接入。
注意:
本文仅作为使用 REST API 数据源读取 Google Sheet 数据的配置参考。Google Sheets API 由第三方提供,其接口协议、认证要求、请求参数或响应结构可能发生变化。实际配置时,请以 Google Sheets API 官方文档 为准;若接口发生变化,您可能需要相应调整请求地址、认证信息、数据路径或字段映射。
方案说明
项目 | 说明 |
数据来源 | |
连接器 | REST API 数据源 |
接入链路 | 离线数据同步 → 文件到表同步(解析数据) |
目标端 | DataBuddy Catalog 下的表(Iceberg 原生表) |
同步方式 |
前提条件
在开始本操作前,请确保满足以下条件:
Google 侧
已创建 Google Cloud 项目,并启用 Google Sheets API(参见 启用 Google Workspace API)。
已获取访问凭据(API Key 或 OAuth 2.0 访问令牌),获取方式见 创建访问凭据 与 步骤 1。
目标 Google Sheet 已录入数据,且首行为表头行;已记录表格的 spreadsheetId 与读取范围。
使用 API Key 认证时,已将表格共享为「知道链接的任何人可查看」。
DataBuddy 侧
已开通 DataBuddy 服务并完成空间初始化。
当前账号在目标 Workspace 中拥有 数据接入相关角色 (详见 成员与权限管理)。
已创建用于数据接入的计算资源(详见 创建计算资源)。
目标 Catalog 与 Schema 已规划好;如目标表不存在,可由本任务一键建表(需要建表权限)。
注意:
DataBuddy 运行环境需要能够访问
https://sheets.googleapis.com。使用限制
限制项 | 说明 |
返回结构 | spreadsheets.get 返回 sheets[].data[].rowData[] 对象数组;每行的单元格位于 values[] 中,可由 REST API Reader 按 JSONPath 读取 |
字段类型 | 本文读取每个单元格的 formattedValue,按字符串处理;日期与数值类型需在字段映射或下游 SQL 中转换 |
认证方式 | REST API 数据源支持无认证 / Basic / Token / OAuth2 密码模式 / OAuth2 客户端模式;Google Sheets API 常用 API Key 与 OAuth 2.0 访问令牌(参见 了解身份验证和授权) |
读取范围 | |
数据结构兼容性 | 不要使用 spreadsheets.values.get 直接作为解析数据来源;其 values 是二维数组,而 REST API Reader 的数组模式要求每条记录为 JSON 对象,否则会触发 JSONArray cannot be cast to JSONObject |
读取配额 |
操作步骤
步骤 1:获取 Google Sheet 的访问信息
1. 打开目标 Google Sheet,从浏览器地址栏复制 spreadsheetId:
https://docs.google.com/spreadsheets/d/{spreadsheetId}/edit#gid=0
2. 确定读取范围,采用 A1 表示法,例如
Sheet1!A1:D1000。不指定工作表名时,默认读取第一个工作表。3. 在 Google Cloud 控制台启用 Google Sheets API,并按 创建访问凭据 创建凭据:
API Key:适用于已共享为「知道链接的任何人可查看」的表格,配置简单,便于快速验证。若 API Key 设置了 IP 或引荐来源限制,需将 DataBuddy 的出口地址加入白名单。
OAuth 2.0 客户端 ID:适用于私有表格。申请只读作用域
https://www.googleapis.com/auth/spreadsheets.readonly,并通过授权流程换取访问令牌(access token)。4. 确认接口返回结构,可在浏览器中访问接口地址查看,返回格式见 spreadsheets.get,示例如下:
{"sheets": [{"data": [{"rowData": [{"values": [{"formattedValue": "order_id"},{"formattedValue": "customer"}]},{"values": [{"formattedValue": "1001"},{"formattedValue": "Alice"}]}]}]}]}
说明:
rowData 是 JSON 对象数组,符合 REST API Reader 的数组解析要求;每行的单元格位于 values 数组中。第一条 rowData 通常对应表头行,配置来源端时需要跳过。尾部空单元格可能不会出现在 values 中,此时对应字段读取为空。步骤 2:创建 REST API 数据源连接
1. 登录 DataBuddy 控制台,在顶部切换到目标地域与 Workspace。
2. 进入 数据集成 > 数据源管理,点击 创建数据源(详见 添加数据源连接)。
3. 数据源类型选择 REST API,按下表填写:
参数 | 示例值 | 说明 |
数据源名称 | google_sheet_demo | 数据源在工作空间内的唯一标识 |
请求地址 (URL) | https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}?includeGridData=true&ranges={range}&key={API_KEY} | 替换 spreadsheetId、range 与 API Key;range 中的 ! 建议编码为 %21,例如 Sheet1%21A1:J11 |
请求头信息 | Accept:application/json | 界面必填项,多个请求头用英文逗号分隔(格式 key1:value1,key2:value2);value 中不要包含逗号 |
认证方式 | 匿名(无需认证) | 使用 API Key 时选此项;Key 已作为 key 参数拼在 URL 中 |
4. 点击 测试连接(参见 数据源连通性测试),测试通过后点击 保存。
注意:
不要选择「用户名+密码」认证方式。该方式对应 HTTP Basic 认证,Google Sheets API 不支持,且会导致用户名、密码变为必填而无法保存。
警告:
1. 任务运行日志会打印完整请求 URL,因此 URL 中的 API Key 也会出现在日志中。请使用专用 Key,仅放行 Google Sheets API;连通性验证通过后按 DataBuddy 出口 IP 配置应用限制,并定期轮换。不要使用能够访问其他服务的通用 Key。
2. 若改用 OAuth 2.0 访问令牌访问私有表格,请在请求头中显式填写
Authorization:Bearer {access_token},不能依赖「Token」认证方式(该方式不会自动注入请求头)。令牌有效期通常为 1 小时,长期调度任务请确认连接器可自动刷新令牌,否则运行期间可能因令牌过期失败。步骤 3:创建离线单表同步任务
1. 进入 数据集成> 接入任务,点击 创建任务,选择 REST API。
2. 填写任务名称(如
load_google_sheet_orders),计算资源选择已创建的平台集群。步骤 4:配置来源端
来源端数据源类型选择 REST API,按下表配置:
参数 | 取值 | 说明 |
源连接 | 步骤 2 创建的连接 | 必填 |
读取方式 | 解析数据 | 解析接口返回内容并写入目标表 |
请求方式 | GET | 读取表格数据固定为 GET |
返回数据类型 | JSON | 返回数据的格式。 |
数据路径 | $.sheets[0].data[0].rowData | 定位到行对象数组 |
返回数据结构 | 数组 | rowData 中每个元素是一行对应的 JSON 对象 |
请求 Header | 使用 API Key 时留空 | 使用 OAuth 2.0 访问令牌时填 Authorization: Bearer {access_token} |
请求参数 | 留空 | includeGridData、ranges 与 key 已拼在数据源 URL 中 |
高级设置 | skipHeader=true | 跳过 rowData 中的第一条表头记录; |
说明:
步骤 5:配置目标端
参数 | 取值 | 说明 |
目标 Catalog | 已规划的 Catalog | 数据写入的 Catalog |
Schema | 已规划的 Schema | 目标 Schema |
Table | ods_google_sheet_orders | 目标表;不存在时可一键建表 |
写入模式 | overwrite | 每次运行全量覆盖;如需保留历史可选 append |
步骤 6:配置字段映射
来源端不读取接口返回的字段元数据,需要按
rowData.values 中的列索引手动添加字段。理解字段路径
字段提取分为两步:
1. 来源端的 数据路径
$.sheets[0].data[0].rowData 先将每个 RowData 对象识别为一条记录。2. 字段映射中的 JSONPath 再以当前
RowData 为根节点,从其 values 数组中读取对应的 CellData。Google 官方说明
RowData.values 表示一行中的各单元格,按列排列;formattedValue 表示单元格向用户显示的格式化值。对应到 DataBuddy:DataBuddy 来源字段 | 含义 | Google 官方依据 |
$.values[0].formattedValue | 读取当前范围内的第 1 列显示值 | RowData.values[0] → CellData.formattedValue |
$.values[1].formattedValue | 读取当前范围内的第 2 列显示值 | RowData.values[1] → CellData.formattedValue |
$.values[n].formattedValue | 读取当前范围内的第 n+1 列显示值 | RowData.values[n] → CellData.formattedValue |
注意:
数组下标相对于所选 range 的起始列,而不是工作表的绝对列号。例如 range 为
C:F 时,$.values[0].formattedValue 对应 C 列,$.values[1].formattedValue 对应 D 列。formattedValue 是只读字符串,保留用户看到的日期、货币、百分比等显示格式。例如数值 0.25 可能读取为 25%。需要底层数值时,应根据 CellData 的 effectiveValue 类型选择 numberValue、stringValue 或 boolValue;不要直接将 effectiveValue 对象映射到普通字段。添加字段映射
1. 点击 添加字段,按列索引依次填写来源字段 JSONPath:
$.values[0].formattedValue、$.values[1].formattedValue,以此类推。2. 选择字段类型,并将来源字段与目标表字段逐一建立映射。
以读取范围
A:J 的订单数据为例,需要配置以下 10 个字段:列索引 | 来源字段 JSONPath | 表头字段 | 建议类型 | 目标字段 |
0 | $.values[0].formattedValue | order_id | STRING | order_id |
1 | $.values[1].formattedValue | product_name | STRING | product_name |
2 | $.values[2].formattedValue | category | STRING | category |
3 | $.values[3].formattedValue | unit_price | DECIMAL(18,2) | unit_price |
4 | $.values[4].formattedValue | quantity | BIGINT | quantity |
5 | $.values[5].formattedValue | total_amount | DECIMAL(18,2) | total_amount |
6 | $.values[6].formattedValue | buyer_name | STRING | buyer_name |
7 | $.values[7].formattedValue | status | STRING | status |
8 | $.values[8].formattedValue | created_at | TIMESTAMP | created_at |
9 | $.values[9].formattedValue | payment_method | STRING | payment_method |
注意:
需要为 Google Sheet 中的每一列添加一条来源字段。若运行日志中的
column 仅有 0、1 两项,则任务只配置了两列,需要补齐到索引 0-9 后再运行。formattedValue 按字符串返回。类型解析失败的数据会进入脏数据;请先确认单元格显示格式,或在下游 SQL 中使用 cast / to_date 等函数转换。Google Sheets API 可能省略行末空单元格,对应来源字段将读取为空。步骤 7:运行设置与调试运行
1. 按需配置并发数、脏数据阈值与限速等运行参数(默认值即可满足一般场景)。
2. 点击 调试运行 ,在任务运维页查看读取行数、写入行数与脏数据条数(参见 离线同步任务运维监控)。
步骤 8:验证结果
1. 任务运行成功后,在 数据目录 或 SQL 探索中查询目标表:
SELECT * FROM {catalog}.{schema}.ods_google_sheet_orders LIMIT 20;
2. 核对目标表行数与 Google Sheet 中的数据行数一致(扣除表头行)。
3. 如需校验字段类型,可执行:
DESCRIBE {catalog}.{schema}.ods_google_sheet_orders;
步骤 9:发布与调度(可选)
常见问题
Q:测试连接报 403 Forbidden 怎么办?
A:403 是使用 API Key 时最高频的阻碍,且不同原因的报错文案相似,需按 Google 返回的
error.details[0].reason 定位。注意:
DataBuddy 会将 Google 的 403 统一包装为「The token is valid but does not have sufficient permissions」。该文案不能用于定位,请点击错误详情查看 Google 原始响应中的
reason 字段。reason | 报错特征 | 原因 | 处理方法 |
SERVICE_DISABLED | Google Sheets API has not been used in project {项目号} before or it is disabled | 项目未启用 Sheets API | |
API_KEY_SERVICE_BLOCKED | Requests to this API sheets.googleapis.com ... are blocked | Key 的「API 限制」未放行 Sheets API | 凭据页 → 该 Key → API restrictions → 勾选 Google Sheets API → 保存 |
PERMISSION_DENIED | The caller does not have permission | 表格未公开共享 | 表格右上角「共享」→ 常规访问权限 → 知道链接的任何人 → 角色「查看者」 |
三种原因可能依次出现——启用 API 后可能暴露 Key 限制问题,修复 Key 后又可能暴露表格共享问题。建议每修一步就重测一次连通性。
快速自检:将带
?key= 的完整 URL 粘贴到浏览器地址栏,能返回 JSON 即表示 Google 侧配置全部正确;仍返回 403 则对照上表处理,返回 400 则参见 接口返回 404 或 400 。另外还需确认:若 Key 设置了 Application restrictions(IP / HTTP 引荐来源限制),需将 DataBuddy 的出口地址加入白名单;测试阶段建议先设为 None,跑通后再收紧。
Q:为什么表格已经授权给账号,用 API Key 还是读不到?
A:这是 API Key 的机制决定的——API Key 不代表任何用户身份,只能访问已公开共享的表格。即使已将某个账号加为协作者,只要表格不是「知道链接的任何人可查看」,用 API Key 就始终返回 403
PERMISSION_DENIED。如需读取私有表格,请改用 OAuth 2.0 认证:创建 OAuth 2.0 客户端 ID,申请只读作用域
https://www.googleapis.com/auth/spreadsheets.readonly,换取访问令牌后在数据源的请求头中填写 Authorization:Bearer {access_token}。令牌有效期通常为 1 小时,详见 使用 Token 认证的任务运行一段时间后失败。Q:接口返回 404 或 400?
A:两类错误均与 URL 中的路径参数有关。
404:spreadsheetId 不正确。请核对浏览器地址栏中的 ID,确认未混入
/edit、#gid=0 等后缀。400
Unable to parse range:range 中的工作表名与实际不符。工作表名精确匹配且区分大小写——Google 新建表格默认首个工作表为 Sheet1(S 大写),写成 sheet1 会解析失败。请核对表格底部的工作表标签名。Q:任务报 JSONArray cannot be cast to JSONObject 怎么办?
A:该错误表示来源端返回的是二维数组,但 Rest API Reader 的数组模式要求数组中的每条记录都是 JSON 对象。典型错误配置如下:
URL: .../spreadsheets/{spreadsheetId}/values/{range}?key=...数据路径: $.values返回结构: 数组 JSON
Google
spreadsheets.values.get 返回的 values 形如 [["表头1","表头2"],["值1","值2"]],每条记录仍是数组,Reader 在将其转换为 JSON 对象时失败。请改为:URL: .../spreadsheets/{spreadsheetId}?includeGridData=true&ranges={range}&key=...数据路径: $.sheets[0].data[0].rowData返回结构: 数组 JSON来源字段: $.values[0].formattedValue、$.values[1].formattedValue、...
注意:
只把数据路径从
$.values 改为其他写法无法解决问题,必须同时改用 spreadsheets.get?includeGridData=true,让接口返回 rowData 对象数组。Q:目标端把表头行也当成数据写入了?
A:来源端需开启 第一行作为字段,并确认 range 从表头行开始(如
A1 而非 A2)。运行日志中应显示 skipHeader=true;若显示 skipHeader=false,表示开关未生效。Q:日期或数值格式异常怎么办?
A:本文读取
formattedValue,它与 Google Sheet 中的单元格显示值一致,例如日期可能为 2026-09-01、金额可能带货币符号。建议先按 STRING 读取,再在字段映射或下游 SQL 中转换;如需原始值,可根据 CellData 的 effectiveValue 结构调整来源字段 JSONPath。Q:表格数据量很大,一次读不完怎么办?
A:将
ranges 拆分为多段(如 Sheet1!A1:D5000、Sheet1!A5001:D10000)分别创建任务。不要直接改用 spreadsheets.values.batchGet,其结果仍包含二维数组,与当前 Rest API Reader 的记录结构不兼容。同时注意 用量限额。Q:写入 TCLake Volume 报 HdfsWriter-02,提示路径不是绝对路径怎么办?
A:目标端的 Volume 目录 必须以
/ 开头。将相对路径 test 改为绝对子路径 /test;写入根目录时填 /。已经选择 Catalog、Schema 与 Volume 后,无需手工填写完整的 gvfs://fileset/... 地址,DataBuddy 会自动拼接。配置项 | 错误示例 | 正确示例 |
Volume 目录 | test | /test |
文件名称 | 与目录混填 | 单独填写,如 google_sheet.txt |
Q:使用 Token 认证的任务运行一段时间后失败?
相关文档
DataBuddy 文档
Google 官方文档