【问题标题】:Google Cloud Pub/Sub - Cloud Function & Bigquery - Data insert is not happeningGoogle Cloud Pub/Sub - Cloud Function & Bigquery - 数据插入未发生
【发布时间】:2019-08-18 20:08:56
【问题描述】:

我正在使用一个 Google Cloud Platform Function,它侦听 Pub/SubTopic 并将数据插入 BigQuery。

我从 pub/sub 控制台传递的输入数据是 JSON 格式 {"NAME", "ABCD"},但从控制台日志中,我可以看到消息以 {NAME, ABCD} 的形式出现,并且在执行期间,它也会出错。我遇到的 2 个常见错误

  1. SyntaxError: JSON 中的意外标记 n 位于 Export.helloPubSub 的 Object.parse (native) 的位置 1"

  2. “错误:{ 错误:'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);
      }
    });
  };

【问题讨论】:

    标签: google-bigquery google-cloud-functions google-cloud-pubsub


    【解决方案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"} 格式。现在正在选择并正确插入消息。现在使用不同的数据集进行测试。如果有更多问题,我会在这里更新。再次感谢
    猜你喜欢
    • 1970-01-01
    • 2022-01-01
    • 2022-01-13
    • 2021-02-21
    • 2019-09-20
    • 2021-12-12
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    相关资源
    最近更新 更多