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 的主/从模式

如何修改后台 Cloud Function 的 Google Cloud Pub/Sub 订阅确认截止日期

Google Cloud Pub/Sub 确认

Google Cloud Pub/Sub 获取或创建订阅

Google Cloud Functions 无法使用 Pub/Sub 死信主题