用于读取记录数组的 BigQuery Java API:“不支持按名称检索字段值”异常

Posted

技术标签:

【中文标题】用于读取记录数组的 BigQuery Java API:“不支持按名称检索字段值”异常【英文标题】:BigQuery Java API to read an Array of Record : "Retrieving field value by name is not supported" exception 【发布时间】:2018-01-18 11:41:01 【问题描述】:

我在 BigQuery 中的当前表有一个使用复杂类型的列。 “family”列实际上是一个记录列表(“重复”功能)(有 2 个字段:id 和 name)。

当我尝试使用以下语法获取 1 行的第一个“id”值时:

FieldValueList c = qr.getValues().iterator().next();    
c.get("family").getRepeatedValue().get(0).getRecordValue().get("id");

我得到了例外:

Method threw 'java.lang.UnsupportedOperationException' exception.
Retrieving field value by name is not supported when there is no fields schema provided

这有点烦人,因为我的表有一个明确定义的架构。当我使用相同的 Java 调用执行“读取”查询时,我还可以看到该模式已正确找到:

qr.getSchema().getFields().get("family").getSubFields().toString();
-->
[Fieldname=id, type=INTEGER, mode=NULLABLE, description=null, Fieldname=name, type=STRING, mode=NULLABLE, description=null]

由于此异常,我发现的解决方法是传递记录字段的“索引”而不是为其命名

c.get("family").getRepeatedValue().get(0).getRecordValue().get(0).getLongValue();

但是,传递索引而不是名称会显得很尴尬。

有没有更好的方法来获取记录中字段的值在数组中(如果我的列只是一条记录,没有数组,那么我不会得到异常)?

这个异常正常吗?

【问题讨论】:

【参考方案1】:

您可以使用“of”静态方法将未命名的 FieldValueList 包装为已命名的字段:

FieldList subSchema = qr.getSchema().getFields().get("family").getSubFields();
FieldValueList c = qr.getValues().iterator().next();
FieldValueList.of(
  c.get("family").getRepeatedValue().get(0).getRecordValue(),
  subSchema).get("id");

“of”方法采用 FieldValueList(在本例中由 getRecordValue() 返回)和 FieldList(此处为子架构),并返回相同的 FieldValueList 但具有命名访问权限。

【讨论】:

以上是关于用于读取记录数组的 BigQuery Java API:“不支持按名称检索字段值”异常的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 存储过程,用于捕获表名以及该表名的记录数

用于读取 JSON 格式数据的 BigQuery 表 URL

用于合并值列表/数组的 BigQuery JavaScript UDF

Bigquery 命令行工具,用于从文件中读取长查询字符串

记录所有 BigQuery 查询

Google BigQuery 将行读入数组