将一个特定的PCollection写入BigQuery

时间:2017-10-18 09:50:11

标签: google-cloud-dataflow apache-beam

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

基本上我的用例是我正在尝试使Write_Append和Write_Truncate动态化。我从我在BigQuery中维护的配置表中获取信息(append / truncate)。因此,根据配置表中的内容,我必须应用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));

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

P.S。我正在使用Java SDK(Apache Beam 2.1)

1 个答案:

答案 0 :(得分:0)

我相信你是对的,如果您的管道包含 at all 使用WRITE_TRUNCATE写入BigQuery表,那么即使没有数据,该表也会被截断。在这种情况下,请随意file a JIRA以支持更多可配置的行为。

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

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