假设我有一个PCollection<Foo>
并且我想将它写入多个BigQuery表,为每个Foo
选择一个可能不同的表。
如何使用Apache Beam BigQueryIO
API执行此操作?
答案 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