假设我作为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)
答案 0 :(得分:0)
我相信你是对的,如果您的管道包含 at all 使用WRITE_TRUNCATE写入BigQuery表,那么即使没有数据,该表也会被截断。在这种情况下,请随意file a JIRA以支持更多可配置的行为。
因此,如果您希望它有条件地不被截断,您需要有条件地不包括该写入转换。有没有办法将条件推送到该级别,或者实际上是否必须从管道中的其他数据计算条件?
(我能想到的唯一解决方法是使用DynamicDestinations来动态选择要截断的表的名称,并截断一些其他虚拟空表 - 我可以在回答上一段后再详细说明)< / p>