在Apache Beam中为不同的BigQuery表写入不同的值

时间:2017-04-19 20:32:20

标签: google-bigquery google-cloud-dataflow apache-beam

假设我有一个PCollection<Foo>并且我想将它写入多个BigQuery表,为每个Foo选择一个可能不同的表。

如何使用Apache Beam BigQueryIO API执行此操作?

2 个答案:

答案 0 :(得分:22)

使用最近添加到Apache Beam中的BigQueryIO的功能可以实现这一点。

PCollection<Foo> foos = ...;
foos.apply(BigQueryIO.write().to(new SerializableFunction<ValueInSingleWindow<Foo>, TableDestination>() {
  @Override
  public TableDestination apply(ValueInSingleWindow<Foo> value) {  
    Foo foo = value.getValue();
    // Also available: value.getWindow(), getTimestamp(), getPane()
    String tableSpec = ...;
    String tableDescription = ...;
    return new TableDestination(tableSpec, tableDescription);
  }
}).withFormatFunction(new SerializableFunction<Foo, TableRow>() {
  @Override
  public TableRow apply(Foo foo) {
    return ...;
  }
}).withSchema(...));

根据输入PCollection<Foo>是有界限还是无界限,这将创建多个BigQuery导入作业(每个表一个或多个,具体取决于数据量),或者它将使用BigQuery流插入API。

最灵活的API版本使用DynamicDestinations,它允许您使用不同的模式为不同的表写入不同的值,甚至允许您在所有这些计算中使用来自管道其余部分的侧输入

此外,BigQueryIO已经重构为许多可重用的转换,您可以自己组合以实现更复杂的用例 - 请参阅files in the source directory

此功能将包含在Apache Beam的第一个稳定版本中,并将包含在Dataflow SDK的下一个版本中(该版本将基于Apache Beam的第一个稳定版本)。现在你可以通过从github上的HEAD的梁快照运行你的管道来使用它。

答案 1 :(得分:0)

从Beam 2.12.0开始,Python SDK中也提供了此功能。它被标记为实验性的,因此您必须通过--experiments use_beam_bq_sink才能启用它。您会这​​样做:

def get_table_name(element):
  if meets_some_condition(element):
    return 'mytablename1'
  else:
    return 'mytablename2'


p = beam.Pipeline(...)

my_input_pcoll = p | ReadInMyPCollection()

my_input_pcoll | beam.io.gcp.bigquery.WriteToBigQuery(table=get_table_name)

新接收器支持许多其他选项,您可以review in the pydoc