【问题标题】:Write a particular PCollection to BigQuery将特定的 PCollection 写入 BigQuery
【发布时间】:2017-10-18 09:50:11
【问题描述】:

假设我创建了两个输出 PCollection 作为 SideOutputs 的结果,并且根据某些条件我只想将其中一个写入 BigQuery。这该怎么做?

基本上我的用例是我试图使 Write_Append 和 Write_Truncate 动态化。我从我在 BigQuery 中维护的配置表中获取信息(追加/截断)。因此,根据我在配置表中的内容,我必须应用 Truncate 或 Append。

因此,使用 SideOutputs 我能够创建两个 PCollections(分别为 Append 和 Truncate),其中一个将为空。并且必须将包含所有行的行写入 BigQuery。这种方法正确吗?

我正在使用的代码:

 final TupleTag<TableRow> truncate =
                  new TupleTag<TableRow>(){};
              // Output that contains word lengths.
              final TupleTag<TableRow> append =
                  new TupleTag<TableRow>(){};

              PCollectionTuple results = read.apply("convert to table row",ParDo.of(new DoFn<String,TableRow>(){
              @ProcessElement
              public void processElement(ProcessContext c)
              {
                  String value = c.sideInput(configView).get(0).toString();
                  LOG.info("config: "+value);
                  if(value.equals("truncate")){
                      LOG.info("outputting to truncate");
                      c.output(new TableRow().set("color", c.element()));
                  }
                  else
                  {
                      LOG.info("outputting to append");
                      c.output(append,new TableRow().set("color", c.element()));
                  }
                  //c.output(new TableRow().set("color", c.element()));
              }
          }).withSideInputs(configView).withOutputTags(truncate,
                  TupleTagList.of(append)));

              results.get(truncate).apply("truncate",BigQueryIO.writeTableRows()
                        .to("projectid:datasetid.tableid")
                        .withSchema(schema)
                        .withWriteDisposition(BigQueryIO.Write.WriteDisposition.WRITE_TRUNCATE)
                        .withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_IF_NEEDED));

              results.get(append).apply("append",BigQueryIO.writeTableRows()
                        .to("projectid:datasetid.tableid")
                        .withSchema(schema)
                        .withWriteDisposition(BigQueryIO.Write.WriteDisposition.WRITE_APPEND)
                        .withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_IF_NEEDED));

我需要执行两者中的一个。如果我做这两个表无论如何都会被截断。

附:我正在使用 Java SDK (Apache Beam 2.1)

【问题讨论】:

  • 这是一个普遍的问题“这种方法是否正确?”还是你想要一些代码解决方案?
  • @Marcin Zablocki 两者都...我也想有一些代码解决方案
  • 你说你有两个PCollections,那么有什么问题呢?拆分和写入的方法似乎还可以。
  • @MarcinZablocki 是的,但我只想写其中一个。如果我两者都写,并且我只想追加,即使其对应的 PCollection 有 0 行/元素,也会发生截断。
  • 但是你说一个会是空的。那么,你为什么不能让它保持原样呢?如果为空,则不会写入任何内容。

标签: google-cloud-dataflow apache-beam


【解决方案1】:

我相信您是对的,如果您的管道完全使用 WRITE_TRUNCATE 写入 BigQuery 表,则当前即使没有数据,该表也会被截断。在这种情况下,请随时 file a JIRA 支持更多可配置的行为。

因此,如果您希望它有条件地不被截断,则需要有条件地根本不包含该写入转换。有没有办法将条件推到那个级别,还是实际上必须从管道中的其他数据计算条件?

(我能想到的唯一解决方法是使用 DynamicDestinations 动态选择要截断的表的名称,并截断其他一些虚拟空表 - 我可以在您对上一段的回答后详细说明)

【讨论】:

  • 嗨@jkff...一种将条件推到那个级别的方法是我期望在这里找到的解决方案...是的,它必须从我检索的数据中计算出来显示 APPEND 或 TRUNCATE 的配置表......所以如果有使用 DynamicDestinations 的解决方法,我真的很想知道......
  • 你能不能在你的主程序中说 if (condition) { p.apply(...APPEND...) } else { p.apply(...TRUNCATE...) } ?或者条件本身是否依赖于管道计算的数据,并且无法由构建管道的主程序评估?
  • 它取决于管道计算的数据
猜你喜欢
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 1970-01-01
  • 2021-12-15
相关资源
最近更新 更多