Google Cloud Functions:使用非标准键将 GCS JSON 文件加载到 BigQuery
Google Cloud Functions: loading GCS JSON files into BigQuery with non-standard keys
我有一个 Google Cloud Storage 存储桶,遗留系统会在其中删除 NEW_LINE_DELIMITED_JSON 需要加载到 BigQuery 中的文件。
我编写了一个 Google 云函数,它获取 JSON 文件并将其加载到 BigQuery。该函数适用于示例 JSON 文件 - 问题是遗留系统正在生成带有非标准密钥的 JSON:
{
"id": 12345,
"@address": "XXXXXX"
...
}
当然,“@address”键会抛出所有内容,云函数会出错...
对于 "ignore" 具有非标准键的 JSON 字段是否有任何选项?或者提供映射并忽略不在映射中的任何 JSON 字段?我环顾四周,看看是否可以停用自动检测并提供我自己的映射,但在线文档没有涵盖这种情况。
我正在考虑以下选项:
- 正在将内存中的文件加载到字符串变量中
- 用地址替换@address
- 将 json 分隔的新行转换为字典列表
- 使用bigquery stream insert在BQ中插入行
但我担心这会花费更长的时间,文件大小可能超过函数的最大 2Gb,在变量中加载文件时处理 unicode,等等等等。
我还有哪些其他选择?
不,我不能修改遗留系统来重命名“@address”字段:(
谢谢!
我假设您遇到的错误是这样的:
Errors: query: Invalid field name "@address". Fields must contain
only letters, numbers, and underscores, start with a letter or
underscore, and be at most 128 characters long.
这是 BigQuery 端的错误消息,因为 BigQuery 中的 cols/fields 有命名限制。因此,在将文件加载到 BigQuery 之前,您必须清理文件。
这是一种完全无服务器的方法:
- 创建一个云函数以在新文件到达存储桶时触发。你已经通过事物的声音完成了这部分。
- 创建一个 templated Cloud Dataflow 管道,当新文件到达时由 Cloud Function 触发。它只是将要处理的文件的名称传递给管道。
- 在上述 Cloud Dataflow 管道中,将 JSON 文件读入
ParDo
,并使用 JSON 解析库(例如,如果您使用 Java,则使用 Jackson) ,在创建输出 TableRow
对象之前读取对象并去掉“@”。
- 将结果写入 BigQuery。在幕后,这实际上会调用 BigQuery 加载作业。
总而言之,您需要在 conga 行中添加以下内容:
File > GCS > Cloud Function > Dataflow (template) > BigQuery
这样做的优点:
- 事件驱动
- 可扩展
- Serverless/no-ops
- 您可以使用 Stackdriver 获得开箱即用的监控警报
- 最小代码
参见:
- https://cloud.google.com/dataflow/docs/templates/overview
- https://shinesolutions.com/2017/03/23/triggering-dataflow-pipelines-with-cloud-functions/
披露:最后一个 link 是我的一位工程师写的博客。
我有一个 Google Cloud Storage 存储桶,遗留系统会在其中删除 NEW_LINE_DELIMITED_JSON 需要加载到 BigQuery 中的文件。
我编写了一个 Google 云函数,它获取 JSON 文件并将其加载到 BigQuery。该函数适用于示例 JSON 文件 - 问题是遗留系统正在生成带有非标准密钥的 JSON:
{
"id": 12345,
"@address": "XXXXXX"
...
}
当然,“@address”键会抛出所有内容,云函数会出错...
对于 "ignore" 具有非标准键的 JSON 字段是否有任何选项?或者提供映射并忽略不在映射中的任何 JSON 字段?我环顾四周,看看是否可以停用自动检测并提供我自己的映射,但在线文档没有涵盖这种情况。
我正在考虑以下选项:
- 正在将内存中的文件加载到字符串变量中
- 用地址替换@address
- 将 json 分隔的新行转换为字典列表
- 使用bigquery stream insert在BQ中插入行
但我担心这会花费更长的时间,文件大小可能超过函数的最大 2Gb,在变量中加载文件时处理 unicode,等等等等。
我还有哪些其他选择?
不,我不能修改遗留系统来重命名“@address”字段:(
谢谢!
我假设您遇到的错误是这样的:
Errors: query: Invalid field name "@address". Fields must contain only letters, numbers, and underscores, start with a letter or underscore, and be at most 128 characters long.
这是 BigQuery 端的错误消息,因为 BigQuery 中的 cols/fields 有命名限制。因此,在将文件加载到 BigQuery 之前,您必须清理文件。
这是一种完全无服务器的方法:
- 创建一个云函数以在新文件到达存储桶时触发。你已经通过事物的声音完成了这部分。
- 创建一个 templated Cloud Dataflow 管道,当新文件到达时由 Cloud Function 触发。它只是将要处理的文件的名称传递给管道。
- 在上述 Cloud Dataflow 管道中,将 JSON 文件读入
ParDo
,并使用 JSON 解析库(例如,如果您使用 Java,则使用 Jackson) ,在创建输出TableRow
对象之前读取对象并去掉“@”。 - 将结果写入 BigQuery。在幕后,这实际上会调用 BigQuery 加载作业。
总而言之,您需要在 conga 行中添加以下内容:
File > GCS > Cloud Function > Dataflow (template) > BigQuery
这样做的优点:
- 事件驱动
- 可扩展
- Serverless/no-ops
- 您可以使用 Stackdriver 获得开箱即用的监控警报
- 最小代码
参见:
- https://cloud.google.com/dataflow/docs/templates/overview
- https://shinesolutions.com/2017/03/23/triggering-dataflow-pipelines-with-cloud-functions/
披露:最后一个 link 是我的一位工程师写的博客。