通过BigQuery库发送的时间戳记对象返回错误“此字段不是记录”

时间:2018-09-27 09:50:49

标签: datetime google-bigquery

在将日期字段作为对象发送到类型为时间戳的BigQuery表时,Google Java API库不会引发异常,但不会导致数据登陆。检查“ InsertAllResponse”响应类型返回的错误包括“此字段不是记录”错误。

例如

current==sortedList

然后

Hashmap<String,Object> rowContent = new Hashmap<>();
rowContent.put("Time", new Date());
rowContent.put("Name", "Harry");

返回一个response.hasErrors()true。

也报告了python herefirebase herejavascript here

2 个答案:

答案 0 :(得分:1)

似乎将日期作为对象发送会导致客户端API创建JSON记录而不是单个字段(这也表明datetime类型尚未显式映射,因此可能会引入时区问题。)

相反,自1970年起,将日期/时间以UTC发送,即修改上面的内容:

Hashmap<String,Object> rowContent = new Hashmap<>();
rowContent.put("Time", Math.floor(new Date()/1000));
rowContent.put("Name", "Harry");

(注意:不确定如何处理毫秒,请参见例如BigQuery not dealing with timestamp in millisecond with partition column,我会找出并返回)

答案 1 :(得分:0)

遗憾的是,BigQuery 的 Java API 将 Java 类型转换为 BigQuery 类型,但未公开。在 BigQuery Timestamp 的情况下,Java API 将 float 和 int 转换为自 Unix Epoch 以来截断的整数。这很愚蠢,因为几乎每个人都使用毫秒,因为 Unix Epoch 和 Timestamp 支持高达微秒的精度。如果您对秒没问题,请使用 int 作为秒。

如果您需要更高的准确性,请将您的时间戳值转换为字符串。根据 this documentation 的规范字符串是:

YYYY-[M]M-[D]D[( |T)[H]H:[M]M:[S]S[.DDDDDD]][time zone] 

这是一个 Java 代码示例,其中 'milliseconds' 存储自 Unix Epoch 以来的毫秒数,但您可以使用您可能碰巧拥有的任何 DateTime:

long milliseconds = 1610399564959L;
LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneOffset.UTC);
DateTimeFormatter timestampFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
String timestampText = dateTime.format(timestampFormatter);
rowContent.put("Time", timestampText);

我真的希望 Google 在某处记录这些转换。