在 BigQuery 中插入时嵌套在数组中的 JSON 对象出现问题

fro*_*fro 3 javascript arrays json node.js google-bigquery

我很难理解我正在做的嵌套出了什么问题。我想使用他们的 Nodejs 客户端在 Google Big Query 中插入一行。为此,我需要推送嵌套在数组中的 json 对象,如下所示:

[ { timestamp: '1533564208', device_id: '2nd_test', temperature: '20.0' } ]
Run Code Online (Sandbox Code Playgroud)

当在我的代码中硬编写此代码时,我可以毫无问题地在 Big Query 中添加一行。

const rows = [
{ timestamp: '1533564208', device_id: '2nd_test', temperature: '20.0' }
];

bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
Run Code Online (Sandbox Code Playgroud)

现在我真正想做的是将我从 pubsub 获得的有效负载插入到 Big Query 中,这就是我面临问题的地方。pubsub 数据的管理如下:

var payload = Buffer.from(pubsubMessage.data, 'base64').toString();
console.log(payload);
// [ { timestamp: '1533564208', device_id: '2nd_test', temperature: '20.0' } ] 
Run Code Online (Sandbox Code Playgroud)

根据日志,它应该可以工作 - 它是一个嵌套在数组中的 JSON 对象,但是当它调用 Big Query API 时,它会遇到无效值错误:

error: ERROR: { ApiError: Invalid value at 'rows[0].json' (type.googleapis.com/google.protobuf.Struct), "[ { timestamp: '1533564208', device_id: '2nd_test', temperature: '20.0' } ]"
at Object.parseHttpRespBody (/Users/marion/google_iot_core_test/google_function/timeseriesBigQuery/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:193:30)
at Object.handleResp (/Users/marion/google_iot_core_test/google_function/timeseriesBigQuery/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:131:18)
at /Users/marion/google_iot_core_test/google_function/timeseriesBigQuery/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:496:12
at Request.onResponse [as _callback] (/Users/marion/google_iot_core_test/google_function/timeseriesBigQuery/node_modules/retry-request/index.js:198:7)
at Request.self.callback (/Users/marion/google_iot_core_test/google_function/timeseriesBigQuery/node_modules/request/request.js:185:22)
at emitTwo (events.js:126:13)
at Request.emit (events.js:214:7)
at Request.<anonymous> (/Users/marion/google_iot_core_test/google_function/timeseriesBigQuery/node_modules/request/request.js:1161:10)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
code: 400,
errors: 
 [ { message: 'Invalid value at \'rows[0].json\' (type.googleapis.com/google.protobuf.Struct), "[ { timestamp: \'1533564208\', device_id: \'2nd_test\', temperature: \'20.0\' } ]"',
   domain: 'global',
   reason: 'badRequest' } ],
response: undefined,
message: 'Invalid value at \'rows[0].json\' (type.googleapis.com/google.protobuf.Struct), "[ { timestamp: \'1533564208\', device_id: \'2nd_test\', temperature: \'20.0\' } ]"' }
Run Code Online (Sandbox Code Playgroud)

编辑:我深入研究了哪些值会给我 rows[0] ,并且出于某种未知的原因,它似乎将其视为字符串并只返回以下内容

console.log(rows[0]);
// [
Run Code Online (Sandbox Code Playgroud)

代替

// { timestamp: '1533564208', device_id: '2nd_test', temperature: '20.0' }
Run Code Online (Sandbox Code Playgroud)

但是当我尝试 JSON.parse 时它会发出错误。

知道问题是什么吗?

谢谢!

fro*_*fro 5

正如评论中提到的,问题是我没有发送有效的 JSON 字符串。难以理解的是,在代码中硬编码的以下两个版本会给我相同的结果并且工作正常。

{ timestamp: "1533564208", device_id: "2nd_test", temperature: "20.0" } 
Run Code Online (Sandbox Code Playgroud)

'{"timestamp":"1533564208","device_id":"2nd_test","temperature":"20.0"}'
Run Code Online (Sandbox Code Playgroud)

但是当使用 PubSub Gcloud 和 Buffer 函数时,我必须确保传入

'{"timestamp":"1533564208","device_id":"2nd_test","temperature":"20.0"}' 
Run Code Online (Sandbox Code Playgroud)

并不是

{ timestamp: "1533564208", device_id: "2nd_test", temperature: "20.0" } 
Run Code Online (Sandbox Code Playgroud)

否则它不会将其视为有效的 JSON。