从 BigQuery 结果 PCollection<TableRow> 获取 TableSchema

Get TableSchema from BigQuery result PCollection<TableRow>

当我 运行 在 BigQuery Web UI 中查询时,结果显示在 table 中,其中每个字段的名称和类型都是已知的(即使字段是COUNT(), AVG(), ... 操作的结果,字段类型当然是已知的)。 然后可以将结果直接导出为 table/json/csv.

我的问题是,当我在 java 项目中检索查询结果时,例如有一个查询:

String query =  "SELECT nationality, COUNT(DISTINCT personID) AS population 
                 FROM Dataset.Table 
                 GROUP BY nationality";

PCollection<TableRow> result = p.apply(BigQueryIO.Read.fromQuery(query));

...是否可以在 result PCollection 中获取 TableRow 的架构,而无需明确定义它? 我认为这一定是可能的,因为在使用 BigQuery Web UI 时可以使用相同的查询。 但是我不知道该怎么做...

TableSchema schema =  // function of PCollection<TableRow> result ?

result.apply(BigQueryIO.Write
                .named("Write Results Table")
                .to(getTableReference(tableName))
                .withSchema(schema));

这样查询结果总是会自动 exported/saved 到一个新的 table 中(然后只需要明确提供 table 名称)。

有什么想法吗?任何帮助将不胜感激:)

遗憾的是,Dataflow SDK 不会公开 BigQuery 通过 Dataflow 的 BigQueryIO API 返回的架构。数据流 API 中没有 "good" 解决方法。

手动定义模式是一种解决方法。

或者,您可以在构建管道时通过 jobs: query 直接对 BigQuery 进行单独查询,然后可以将其结果传递给 BigQueryIO.Write 转换。这可能会产生额外的成本,但可以通过稍微更改查询以减少处理的数据量来减轻这种成本。输出的正确性无关紧要,因为您只会存储模式。

从概念上讲 - 您应该编写将遍历给定 TableRow 的所有单元格的函数,并为每个 - 获取名称和类型,并在迭代时创建相应的 TableSchema。
对于简单的模式,我希望它应该相对容易。
对于有记录、重复等的模式,这可能更复杂