我有一个树莓派和建立一个天气(和土壤湿度)钻机。
我找到了这个指南:https://codelabs.developers.google.com/codelabs/iot-data-pipeline,我跟随它,并被困在第6-7步。
据我所知,当我向PubSub发送数据时,什么都不会发生。在Raspberry端,我有这样的想法:数据正在发送,但不会传递到BigQuery。我做了一些打印声明,在不同的点,试图看看它在哪里卡住了。
当我试图查找错误时,我慢慢地返回到步骤5(创建一个云函数)。步骤5和我复制的相关代码可以在这里看到:https://codelabs.developers.google.com/codelabs/iot-data-pipeline/#4
在GCP中-我点击云函数->函数- ->测试(选项卡)
在标题-触发器事件下,我填写了下面的JSON:
{
"sensorID":"Raspberry",
"timecollected":"2020-09-11 06:45:19",
"zipcode":"00000",
"latitude":"0.0",
"longitude":"0.0",
"temperature":"-273",
"humidity":"-1",
"dewpoint":"-273",
"pressure":"0"
}当我单击-测试函数时,输出如下所示
**Error: function execution failed. Details:
Cannot read property 'data' of undefined**我猜这两件事中有一件是造成这个问题的。PubSubMessage.data或event.data
我试图对代码做一些修改,但我只是在黑暗中拍摄。
我在想,如果:
提前谢谢。
发布于 2020-09-14 22:23:21
TLDR:本教程已经过时,不使用__,除非您想要面对多个问题,并且希望以艰苦的方式学习
我读完了教程,我能够复制这个问题。还有更多。正如您已经提到的,这个教程已经过时了,很多事情都已经改变了,您可以通过查看图片并注意到UI是不同的,所以我不会向GCP新手推荐本教程。
第一期:
**Error: function execution failed. Details: Cannot read property 'data' of undefined**可以通过查看对发布/订阅消息的期望的结构来轻松解决:
{
"data": string,
"attributes": {
string: string,
...
},
"messageId": string,
"publishTime": string,
"orderingKey": string
}很容易对吧?但是,一旦您像我一样用自己的变量模拟了消息的结构:
{
"data": "",
"attributes": {
"sensorID":"Raspberry",
"timecollected":"2020-09-11 06:45:19",
"zipcode":"00000",
"latitude":"0.0",
"longitude":"0.0",
"temperature":"-273",
"humidity":"-1",
"dewpoint":"-273",
"pressure":"0"
},
"messageId": "id_1",
"publishTime": "2014-10-02T15:01:23Z",
"orderingKey": ""
}您将得到一个关于JSON的错误:
SyntaxError: Unexpected token ' in JSON at position 1此错误是由于在变量'内部构造JSON时使用了incomingData,因此必须更改第一个变量声明,我使用模板文字:
const incomingData = PubSubMessage.data ? Buffer.from(PubSubMessage.data, 'base64').toString() : `{"sensorID": "na","timecollected":"01/01/1970 00:00:00","zipcode":"00000","latitude":"0.0","longitude":"0.0","temperature":"-273","humidity":"-1","dewpoint":"-273","pressure":"0"}`;但是问题还没有结束,在尝试插入BigQuery时做了一些测试之后,我得到了一个关于插入的错误,但是不知道实际发生了什么,所以我用外部脚本隔离了查询,发现错误处理是错误的,我建议您更改的第一件事是package.json中的BigQuery版本:
"@google-cloud/bigquery": "^0.9.6"转到
"@google-cloud/bigquery": "5.2.0"这是写这个答案时的最后一个版本。下一部分是将使用BigQuery构造函数的方式重新定义为:
const bigquery = new BigQuery({
projectId: projectId
});经过多次测试后,我发现catch并没有像预期的那样完成它的工作,所以必须将该部分重写为:
bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
.then((foundErrors) => {
rows.forEach((row) => console.log('Inserted: ', row));
if (foundErrors && foundErrors.insertErrors != undefined) {
foundErrors.forEach((err) => {
console.log('Error: ', err);
})
}
})
.catch((err) => {
bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
.then((foundErrors) => {
rows.forEach((row) => console.log('Inserted: ', row));
if (foundErrors && foundErrors.insertErrors != undefined) {
foundErrors.forEach((err) => {
console.log('Error: ', err);
})
}
})
.catch((err) => {
if(err.name=='PartialFailureError'){
if (err && err.response.insertErrors != undefined) {
err.response.insertErrors.forEach((errors) => {
console.log(errors);
})
}
}else{
console.log("GENERIC ERROR:",err)
}
});
});在此之后,您将最终注意到错误是由于(再次) incomingData变量造成的:
Could not parse \'01/01/1970 00:00:00\' as a timestamp. Required format is YYYY-MM-DD HH:MM[:SS[.SSSSSS]]'您必须将日期从01/01/1970 00:00:00更改为1970-01-01 00:00:00。
还和我在一起吗?另外还有一个错误来自CF末尾callback的使用:
这是因为云函数现在需要三个参数,回调是最后一个,所以将函数声明改为:
exports.subscribe = function (event, context, callback)在所有这些之后,您已经能够将数据插入到BigQuery中,但是我们使用的是局部变量,而不是来自pub/sub的数据,此时我放弃了,因为我需要实际重写整个函数,以便使用属性而不是data来工作。
因此,正如前面提到的,如果您是从GCP世界开始的,请不要遵循本教程。
https://stackoverflow.com/questions/63847851
复制相似问题