使用流 API 更新新列后无法将新值插入 BigQuery 表

2024-03-25

我在 bigquery 表中发现了一些奇怪的行为,我刚刚创建了一个新列,在表中添加了一个新列,它在界面上看起来不错,并通过 api 获取架构。

但是,当向新列添加值时,出现以下错误:

{
  "insertErrors" : [ {
    "errors" : [ {
      "message" : "no such field",
      "reason" : "invalid"
    } ],
    "index" : 0
  } ],
  "kind" : "bigquery#tableDataInsertAllResponse"
}

我正在使用 java 客户端和流 API,我唯一添加的是:

tableRow.set("服务器时间戳", 0)

没有那条线它可以正常工作:(

您发现它有什么问题吗(列的名称是 server_timestamp,它被定义为 INTEGER)


自 2014 年 8 月最初回答此问题以来,BigQuery 的流式传输系统已经发生了重大更新,因此更新了此答案。


BigQuery 的流式处理系统会将表架构缓存最多 2 分钟。当您将字段添加到架构中,然后立即将新行流式传输到表中时,您可能会遇到此错误。

避免此错误的最佳方法是在修改表后延迟流式传输具有新字段的行 2 分钟。

如果这不可能,您还有其他一些选择:

  1. Use the ignoreUnknownValues选项。该标志将告诉插入操作忽略未知字段,并仅接受它识别的那些字段。设置此标志允许您立即开始使用新字段流式传输记录,同时避免在 2 分钟窗口内出现“无此类字段”错误 - 但请注意,新字段值将被静默删除,直到缓存的表架构更新!

  2. Use the skipInvalidRows选项。该标志将告诉插入操作插入尽可能多的行,而不是在检测到单个无效行时使整个操作失败。如果只有部分数据包含新字段,则此选项很有用,因为您可以继续使用旧格式插入行,并单独决定如何处理失败的行(使用ignoreUnknownValues或者等待 2 分钟窗口过去)。

如果您必须捕获所有值并且不能等待 2 分钟,则可以使用更新的架构创建一个新表并流式传输到该表。这种方法的缺点是您需要管理由此方法生成的多个表。请注意,您可以使用以下方式方便地查询这些表TABLE_QUERY,并且您可以运行定期清理查询(或表副本)以将数据合并到单个表中。

历史记录:此答案的先前版本建议用户停止流式传输,将现有数据移动到另一个表,重新创建流式传输表,然后重新启动流式传输。但是,由于这种方法的复杂性以及架构缓存窗口的缩短,BigQuery 团队不再推荐这种方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用流 API 更新新列后无法将新值插入 BigQuery 表 的相关文章

随机推荐