Google bigquery 如何让Google数据流从输入数据写入BigQuery表名?

Google bigquery 如何让Google数据流从输入数据写入BigQuery表名?,google-bigquery,google-cloud-dataflow,apache-beam,Google Bigquery,Google Cloud Dataflow,Apache Beam,我是Dataflow/Beam的新手。我正在尝试向BigQuery写入一些数据。我希望将目标表名从前一阶段引入一个键为“table”的映射条目。但我无法找到如何通过管道将此表名传递给BigQuery。这就是我被困的地方。。你知道下一步该怎么做吗 pipeline // ... //////// I guess I shouldn't output TableRow here? .apply("ToBQRow", ParDo.of(new DoFn<Map<String, String

我是Dataflow/Beam的新手。我正在尝试向BigQuery写入一些数据。我希望将目标表名从前一阶段引入一个键为“table”的映射条目。但我无法找到如何通过管道将此表名传递给BigQuery。这就是我被困的地方。。你知道下一步该怎么做吗

pipeline
// ...
//////// I guess I shouldn't output TableRow here?
.apply("ToBQRow", ParDo.of(new DoFn<Map<String, String>, TableRow>() {
    @ProcessElement
    public void processElement(ProcessContext c) throws Exception {
        ////////// WHAT DO I DO WITH "table"?
        String table = c.element().get("table");
        TableRow row = new TableRow();
        // ... set some records
        c.output(row);
    }
}))
.apply(BigQueryIO.writeTableRows().to(/* ///// WHAT DO I WRITE HERE?? */)
    .withSchema(schema)
    .withWriteDisposition(
        BigQueryIO.Write.WriteDisposition.WRITE_APPEND)
));
管道
// ...
////////我想我不应该在这里输出TableRow?
.apply(“ToBQRow”,第页,共页,共页{
@过程元素
public void processElement(ProcessContext c)引发异常{
//////////“桌子”怎么办?
字符串table=c.element().get(“table”);
TableRow行=新TableRow();
//创造了一些记录
c、 输出(行);
}
}))
.apply(BigQueryIO.writeTableRows().to(//*///我在这里写什么??*/)
.withSchema(schema)
.带书面说明(
BigQueryIO.Write.WriteDisposition.Write_APPEND)
));
您可以使用它

例如,我创建了一些虚拟数据,并将最后一个单词用作键:

p.apply(“创建数据”),Create.of(“这应该转到表一”,
“我想去第一桌”,
“请,一号桌”,
“我更喜欢二号桌”,
“回到一号”,
“我的最爱是一个”,
"支持两人"()
.apply(“创建密钥”,第页,共页,共页)(新DoFn(){
@过程元素
公共void processElement(ProcessContext c){
字符串[]splitBySpaces=c.element().split(“”);
c、 输出(KV.of(splitBySpaces[splitBySpaces.length-1],c.element());
}
}))
然后通过
getDestination
控制如何根据键将每个元素路由到不同的表,并
getTable
构建完全限定的表名(前缀的前缀)。如果不同的表有不同的模式,我们可以使用
getSchema
。最后,我们使用
with formatfunction
控制要在表中写入的内容:

.apply(BigQueryIO.write()
.to(新的动态估计){
公共字符串getDestination(ValueInSingleWindow元素){
返回元素.getValue().getKey();
}
公共TableDestination getTable(字符串名称){
String tableSpec=输出+名称;
返回新的TableDestination(tableSpec,“类型表”+名称);
}
公共表模式getSchema(字符串模式){
列表字段=新的ArrayList();
add(new TableFieldSchema().setName(“Text”).setType(“STRING”);
TableSchema ts=新的TableSchema();
设置字段(字段);
返回ts;
}
})
.withFormatFunction(新的SerializableFunction(){
公共表格行应用(千伏行){
TableRow tr=新的TableRow();
tr.set(“Text”,row.getValue());
返回tr;
}
})
.withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE如果需要);
为了充分测试这一点,我创建了以下表格:

bq mk动态_键
bq mk-f dynamic_key.dynamic_one Text:STRING
bq mk-f dynamic_key.dynamic_两个文本:字符串
并且,在设置了
$PROJECT
$BUCKET
$TABLE\u PREFIX
(在我的例子中是
PROJECT\u ID:dynamic\u key.dynamic\u
)变量之后,我使用以下变量运行作业:

mvn-Pdataflow runner compile-e exec:java\
-Dexec.mainClass=com.dataflow.samples.DynamicTableFromKey\
-Dexec.args=“--project=$project\
--stagingLocation=gs://$BUCKET/staging/\
--tempLocation=gs://$BUCKET/temp/\
--输出=$TABLE_前缀\
--runner=数据流runner“
我们可以验证每个元素是否进入了正确的表格:

$bq query“从动态键中选择*动态键”
+---------------------------------+
|正文|
+---------------------------------+
|请坐一号桌|
|回到原点|
|我最喜欢的是一个|
|这个应该放在第一桌|
|我想去一号桌|
+---------------------------------+
$bq query“从动态键中选择*动态键”
+--------------------+
|正文|
+--------------------+
|我喜欢二号桌|
|支持两个人|
+--------------------+

完整代码。

您应该对此进行研究。非常感谢您的详细解释。我不知道withFormatFunction。这节省了很多努力。