Google Cloud Pub/Sub - Cloud Function & Bigquery - 数据插入未发生
Posted
技术标签:
【中文标题】Google Cloud Pub/Sub - Cloud Function & Bigquery - 数据插入未发生【英文标题】:Google Cloud Pub/Sub - Cloud Function & Bigquery - Data insert is not happening 【发布时间】:2019-08-18 20:08:56 【问题描述】:我正在使用一个 Google Cloud Platform Function,它侦听 Pub/SubTopic 并将数据插入 BigQuery。
我从 pub/sub 控制台传递的输入数据是 JSON 格式 "NAME", "ABCD",但从控制台日志中,我可以看到消息以 NAME, ABCD 的形式出现,并且在执行期间,它也会出错。我遇到的 2 个常见错误
SyntaxError: JSON 中的意外标记 n 位于 Export.helloPubSub 的 Object.parse (native) 的位置 1"
“错误: 错误:'rows[0].json' 处的值无效”
输入给定:
gcloud pubsub topics publish pubsubtopic1 --message "name":"ABCD"
用单引号和方括号以及其他可能的选项尝试了各种格式的输入数据,没有任何帮助
尝试使用 JSON.parse、JSON.stringfy 等解决方法,这有助于避免上面提到的第一个问题,但最终会出现 row[0]
问题
当我将 JSON 输入数据作为"NAME", "ABCD"
等云函数中的硬编码值传递时,数据会正确插入。
/**This is working code since i hardcoded the data in JSON format, commented the lines which i tried and did not helped**/
/**
* Triggered from a message on a Cloud Pub/Sub topic.
*
* @param !Object event Event payload and metadata.
* @param !Function callback Callback function to signal completion.
*/
exports.helloPubSub = (event, callback) =>
const pubsubMessage = event.data;
console.log(Buffer.from(pubsubMessage.data, 'base64').toString());
const BigQuery = require('@google-cloud/bigquery');
const bigquery = new BigQuery();
//console.log(Buffer.from(pubsubMessage.data, 'base64').toString());
//console.log(JSON.parse(Buffer.from(pubsubMessage.data, 'base64').toString()));
var myjson='"NAME":"ABCD","STATE":"HHHH","AGE":"12"';
console.log(myjson);
bigquery
.dataset("DEMO")
.table("EMP")
.insert(JSON.parse(myjson),
'ignoreUnknownValues':true, 'raw':false)
//.insert(JSON.parse(Buffer.from(pubsubMessage.data, 'base64').toString()),
.then ((data) =>
console.log('Inserted 1 rows');
console.log(data);
)
.catch(err =>
if (err && err.name === 'PartialFailureError')
if (err.errors && err.errors.length > 0)
console.log('Insert errors:');
err.errors.forEach(err => console.error(err));
else
console.error('ERROR`enter code here`:', err);
);
;
【问题讨论】:
【参考方案1】:我使用 gcloud 运行了一个快速测试来发布和拉取消息。
使用您提到的语法,我得到以下结果:
gcloud pubsub topics publish pubsubtopic1 --message "name":"ABCD"
gcloud pubsub subscriptions pull pubsubsubscription1
结果是:
数据│name:ABCD
如果您改用此语法:
gcloud pubsub topics publish pubsubtopic1 --message "\"name\":\"ABCD\""
gcloud pubsub subscriptions pull pubsubsubscription1
结果是:
数据 | "name":"ABCD"
编辑 2019-04-01
上面的解决方法是出于测试目的,需要使用转义字符是使用命令行的一个警告。要从您的真实应用程序发布,您可以使用 REST 调用或列出的 here 客户端库。请注意,Pub/Sub API 要求消息采用 base64 编码。例如:
POST https://pubsub.googleapis.com/v1/projects/YOUR_PROJECT_ID/topics/YOUR_TOPIC:publish?key=YOUR_API_KEY
"messages": [
"data": "eyJuYW1lIjoiQUJDRCJ9"
]
【讨论】:
非常感谢迈克,您上面提到的方法非常有效,但我的源数据将始终采用正确的 JSON 格式,没有附加这个“\”。您能否帮助理解为什么我们的 JSON 语法不起作用!根据您的建议,我认为实现此功能的唯一方法是,我们需要找到一种方法,在每次处理源 JSON 数据集时添加“\”。如果您找到更好的解决方案,请提出建议 嗨,我用最新的 cmets 更新了解决方案。 谢谢迈克。您的第一个解决方案对我帮助很大。我在 Cloud 函数中进行了更改,以使用 java 脚本替换方法将 JSON 转换为 "JSON" 格式。现在正在选择并正确插入消息。现在使用不同的数据集进行测试。如果有更多问题,我会在这里更新。再次感谢以上是关于Google Cloud Pub/Sub - Cloud Function & Bigquery - 数据插入未发生的主要内容,如果未能解决你的问题,请参考以下文章
Google Cloud Pub/Sub - Cloud Function & Bigquery - 数据插入未发生
Google Cloud 上使用 Pub/Sub 的主/从模式