当前位置: 首页 > 知识库问答 >
问题:

使用Apache Beam将重复字符串写入BigQuery

孔斌
2023-03-14

我有一个包含字符串的数据流,看起来像JSONArrays。我想解析这些字符串并使用Apache Beam写入BigQuery表,但在写入重复字符串时出现错误。

以下是如何将字符串转换为tableRow:

    String dataString = "[{\"EMAIL\": [\"zog@yahoo.com\"]}]";

    JSONArray jsonArray = new JSONArray(dataString);
    TableRow tableRow = new TableRow();

    for (int i = 0; i < jsonArray.length(); i++) {
      JSONArray emailArray = new JSONArray(jsonArray.getJSONObject(i).get("EMAIL").toString());

      tableRow.set("EMAIL", emailArray); //Results in error
    }

下面是我的BigQuery模式的样子:

[
  {
    "name": "EMAIL",
    "type": "STRING",
    "mode": "REPEATED"
  }
]

我已经设法使用Python为BigQuery表编写了一个类似的重复字符串,但无法使用Apache Beam来完成。我想我没有在tableRow中保存正确的键值对。我现在得到的错误是:

java.io.IOException: Insert failed: [{"errors":[{"debugInfo":"","location":"email","message":"This field is not a record.","reason":"invalid"}],"index":0}]

我需要关于如何保存一个类似的重复字符串到BigQuery而不创建一个记录的帮助,并将感谢任何意见或建议。提前道谢。

共有1个答案

西门奇希
2023-03-14

看来你想创造

  1. 带有电子邮件地址串联字符串的一行,或
  2. 每封电子邮件一行,或
  3. 具有重复字段的一行。

注意,您的validfrom字段似乎属于string类型,而不是重复字段,除非它包装在分层架构中的重复字段中。

在您提供的示例代码中,您正在创建一个JSONARRAY并将其放入String字段,我认为这会导致一些问题,因为类型不兼容。如果希望将其保留为纯字符串字段,可以使用下面的解决方案1。

还要确保BigQuery中的列名与代码中的列名相匹配,我看到您同时使用了validfromemail(但在发布的代码中可能是一个错误)。

如果您想在BigQuery中添加带有级联string字段的一行,可以使用以下方法:

// Initialize your final row
TableRow tableRow = new TableRow();

// Find email addresses
String [] emails = ... // your extraction logic

// Build a concatenated string of emails
String allEmails = String.join(";", emails);

// Add the string field to the row
tableRow.set('EMAILS', allEmails);

如果您想插入多行,请创建多个表行:

// Find email addresses
String [] emails = ... // your extraction logic

// Build a row per email
for(String email: emails) {
    // Initialize your final row
    TableRow tableRow = new TableRow();
    tableRow.set('EMAIL', email);
    
    // TODO: do something with the row (add to list, or ...)
}

如果要在BigQuery中添加带有重复字符串字段的一行,可以使用以下方法:

// Initialize your final row
TableRow tableRow = new TableRow();

// Find email addresses
String [] emails = ... // your extraction logic

// Build the repeated field
List<String> emailCells = new ArrayList<>();
for(String email: emails) {
    emailCells.add(email);
}

// Add the repeated field to the row
tableRow.set('EMAILS', emailCells);

如果这不是你的目标,请提供一些更多的细节。

 类似资料:
  • 问题内容: 我想使用Apache PDFBox 1.8.8创建一个包含Unicode字符的PDF,但是我对支持什么和不支持什么感到困惑。 请有人澄清。另外,如果这是一个已修复的错误,则有人可以告诉我何时可能发布PDFBox的下一个版本。 谢谢。 问题答案: 基本上,您链接到的所有答案都是正确的。您必须记住它们分别引用哪个PDFBox版本。 _关于这个答案 在2.0.0之前的版本(直到当前的1.8.

  • 我有几个输出侦听器正在实现。它可以是写到stdout或文件的,也可以是写到内存或任何其他输出目标;因此,我在方法中指定作为(an)参数。 现在,我收到了。在这里向流写入的最佳方式是什么? 我应该只使用吗?我可以给它字节,但如果目标流是字符流,那么它会自动转换吗? 我需要用这里的一些桥流来代替吗?

  • 问题内容: 我有几个正在实现OutputStream的输出侦听器。它可以是写到stdout或文件的PrintStream,也可以写到内存或任何其他输出目标。因此,我在方法中将OutputStream指定为参数。 现在,我已经收到了字符串。在此处写入流的最佳方法是什么? 我应该只使用Writer.write(message.getBytes())吗?我可以给它提供字节,但是如果目标流是字符流,那么它

  • wef:使用apache poi写入xlsm(Excel 2007) 当我向文件中写入一个简单的字符串时,我无法打开该文件。错误-“Excel无法打开文件“Test1.xlsm”,因为文件格式或文件扩展名无效”

  • 问题 你想重复一个字符串。 解决方案 创建一个包含 n+1 个空元素的数组,然后用要重复的字符串作为连接字符将数组元素拼接到一起: # 创建包含10个foo的字符串 Array(11).join 'foo' # => "foofoofoofoofoofoofoofoofoofoo" 为字符串重复方法 你也可以在字符串的原型中为其创建方法。它十分简单: # 为所有的字符串添加重复方法,这会重复返回

  • 我基本上想把句子中每个单词的第一个字母大写,假设str都是小写的。在这里,我试着一个字母一个字母地拆分字符串,然后使用for循环,我会大写空格后面的字母。这是我的代码,你能指出我哪里的代码错了吗?非常感谢。