BigQuery 流式插入,其中一个函数应用于另一列

Posted

技术标签:

【中文标题】BigQuery 流式插入,其中一个函数应用于另一列【英文标题】:BigQuery streaming insert with a function applied to another column 【发布时间】:2021-12-12 17:27:43 【问题描述】:

使用客户端库时,我可以传递要插入 BigQuery 的对象列表,例如 Go 中的这个 https://cloud.google.com/bigquery/docs/samples/bigquery-table-insert-rows#bigquery_table_insert_rows-go

但是如果我想做这样的事情怎么办:

INSERT INTO table_name (col1, col2)
VALUES
    ("a", FARM_FINGERPRINT("a")),
    ("bcd", FARM_FINGERPRINT("bcd")),

即仅提供值“a”、“bcd”插入到两列中,其中一列只是另一列的函数。

例如,如何在 Go 库中使用流式插入来做到这一点?像这样的伪代码:

...
inserter := client.Dataset(datasetID).Table(tableID).Inserter()
items := []*Item
        // Item implements the ValueSaver interface.
        Name: "Phred Phlyntstone", Age: 32, SomeColumn: 'CALL_ME("Phred Phlyntstone")',
        Name: "Wylma Phlyntstone", Age: 29, SomeColumn: 'CALL_ME("Wylma Phlyntstone")',

...

一种可能性是在 Go 代码中重新实现函数并显式插入,但这并不理想。或者使用简单的 INSERT INTO 我可以达到 DML 限制。有没有更好的解决方案?

【问题讨论】:

【参考方案1】:

根据文档,可能无法使用Inserter() 执行 DML 功能。 Inserter() 接受 Struct、StructSaver 和 ValueSaver 作为“src”。

Struct 由键值对组成,因此无论分配给它们的值是什么,都将是它。类型 StructSaver 接受 Schema、InsertId 和 Struct 作为参数。所以基本上它与传递 Struct 相同,但你可以传递额外的参数。 ValueSaver 接受 Schema、InsertID 和 Row。 Row 是 Value 类型,因此它可以接受任何数据类型的任何值。根据接受的 Inserter() 类型,它们都只接受键值对,无论键值对的值是什么,这将是加载的数据。

不幸的是,最好的解决方法是您提出的建议,即在代码中重新实现该函数,因为它不会达到 DML 限制。您可以尝试创建一个feature request for Go lang 来实现此功能,因为这将是一个很酷的功能。

【讨论】:

【参考方案2】:

传统的流式 API(例如您引用的 Go 插入器)和较新的存储写入 API 都允许将值直接插入到表中。

这不涉及查询引擎,因此无法执行调用函数/UDF/等之类的操作。

另一种可能性:您可以做一些事情,例如构建一个逻辑或物化视图,使用您将数据流式传输到的表作为基表。

【讨论】:

以上是关于BigQuery 流式插入,其中一个函数应用于另一列的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在保留缓存的同时流式传输到 BigQuery 分区表?

BigQuery,Python 批量插入 bigquery 以进行流式传输服务(“告诉”错误)

使用模板表的 BigQuery 流式插入 - 503 错误

使用 AVRO 格式的 BigQuery 流式插入

来自 Dataflow 的 BigQuery 流式插入 - 没有结果

BigQuery 插入作业而不是流式传输