我在我的bigquery表中看到了一些奇怪的行为,我刚刚创建了一个新的列添加到表中,它在界面上看起来很好并通过api获取架构。
但是当向新列添加值时,我收到以下错误:
{
"insertErrors" : [ {
"errors" : [ {
"message" : "no such field",
"reason" : "invalid"
} ],
"index" : 0
} ],
"kind" : "bigquery#tableDataInsertAllResponse"
}
我使用java客户端和流API,我唯一添加的是:
tableRow.set(" server_timestamp",0)
没有那条线就可以正常工作:(
你看到它有什么问题(列的名称是server_timestamp,它被定义为INTEGER)
答案 0 :(得分:9)
更新此答案,因为BigQuery的流媒体系统自2014年8月以来已经看到重大更新,此时此问题最初得到解答。
BigQuery的流式传输系统将表模式缓存最多2分钟。向架构添加字段然后立即将新行流式传输到表时,可能会遇到此错误。
避免此错误的最佳方法是在修改表格后使用新字段延迟流式行2分钟。
如果不可能,您还有其他一些选择:
使用ignoreUnknownValues
选项。此标志将告诉插入操作忽略未知字段,并仅接受它识别的那些字段。设置此标志允许您立即使用新字段开始流式传输记录,同时避免在2分钟窗口期间出现“无此字段”错误 - 但请注意,新字段值将以静默方式删除,直到缓存的表架构更新为止!
使用skipInvalidRows
选项。此标志将告诉插入操作尽可能多地插入行,而不是在检测到单个无效行时使整个操作失败。如果只有部分数据包含新字段,则此选项很有用,因为您可以继续使用旧格式插入行,并分别决定如何处理失败的行(使用ignoreUnknownValues
或等待2分钟窗口通过)。
如果必须捕获所有值并且不能等待2分钟,则可以使用更新的模式创建新表并将流传输到该表。这种方法的缺点是您需要管理这种方法生成的多个表。请注意,您可以使用TABLE_QUERY
方便地查询这些表,并且可以运行定期清理查询(或表副本)以将数据合并到单个表中。
历史记录:此答案的先前版本建议用户停止流式传输,将现有数据移至另一个表,重新创建流式表,然后重新启动流式传输。但是,由于此方法的复杂性和架构缓存的缩短窗口,BigQuery团队不再推荐这种方法。
答案 1 :(得分:2)
我遇到了这个错误。事实证明,我正在构建插入对象,就像我处于“原始”模式但忘记设置标志raw: true
。这导致bigQuery获取我的插入数据并将其再次嵌套在json: {}
节点下。
换句话说,我这样做了:
table.insert({
insertId: 123,
json: {
col1: '1',
col2: '2',
}
});
我应该这样做的时候:
table.insert({
insertId: 123,
json: {
col1: '1',
col2: '2',
}
}, {raw: true});
节点bigquery库没有意识到它已经处于raw
模式,然后尝试插入它:
{
insertId: '<generated value>',
json: {
insertId: 123,
json: {
col1: '1',
col2: '2',
}
}
所以在我的情况下,错误指的是插件期望我的架构中有2列(insertId和json)。