Google cloud dataflow 使用ValueProivder.RuntimeProvider构建管道

Google cloud dataflow 使用ValueProivder.RuntimeProvider构建管道,google-cloud-dataflow,Google Cloud Dataflow,我有一个使用库版本1.9.1的Google数据流作业,该作业采用运行时参数。我们使用了TextIO.read().from().withoutValidation()。自从我们迁移到GoogleDataflow2.0.0以来,withoutValidation在2.0.0中被删除。发行说明页面没有提到这一点 我们尝试将输入作为ValueProvider.RuntimeProvider传递。但是在管道施工过程中,我们得到了以下错误。如果将其作为ValueProvider传递,则管道创建将尝试验证该

我有一个使用库版本1.9.1的Google数据流作业,该作业采用运行时参数。我们使用了TextIO.read().from().withoutValidation()。自从我们迁移到GoogleDataflow2.0.0以来,withoutValidation在2.0.0中被删除。发行说明页面没有提到这一点

我们尝试将输入作为ValueProvider.RuntimeProvider传递。但是在管道施工过程中,我们得到了以下错误。如果将其作为ValueProvider传递,则管道创建将尝试验证该值提供程序。如何在google cloud dataflow 2.0.0中为TextIO输入提供运行时值提供程序

java.lang.RuntimeException:方法getInputFile不应具有返回类型RuntimeValueProvider,请改用ValueProvider。
在org.apache.beam.sdk.options.ProxyInvocationHandler.getDefault(ProxyInvocationHandler.java:505)

中,我假设您使用的是模板化管道,并且您的管道正在使用运行时参数。下面是一个使用云数据流SDK版本2.1.0的工作示例。它从GCS读取一个文件(在运行时传递给模板),将每一行转换为
TableRow
,并写入BigQuery。这是一个简单的示例,但它适用于
2.1.0

程序参数如下所示:

 --project=<your_project_id>
 --runner=DataflowRunner
 --templateLocation=gs://<your_bucket>/dataflow_pipeline
 --stagingLocation=gs://<your_bucket>/jars
 --tempLocation=gs://<your_bucket>/tmp
public class TemplatePipeline {
    public static void main(String[] args) {
        PipelineOptionsFactory.register(TemplateOptions.class);
        TemplateOptions options = PipelineOptionsFactory
                .fromArgs(args)
                .withValidation()
                .as(TemplateOptions.class);
        Pipeline pipeline = Pipeline.create(options);
        pipeline.apply("READ", TextIO.read().from(options.getInputFile()).withCompressionType(TextIO.CompressionType.GZIP))
                .apply("TRANSFORM", ParDo.of(new WikiParDo()))
                .apply("WRITE", BigQueryIO.writeTableRows()
                        .to(String.format("%s:dataset_name.wiki_demo", options.getProject()))
                        .withCreateDisposition(CREATE_IF_NEEDED)
                        .withWriteDisposition(WRITE_TRUNCATE)
                        .withSchema(getTableSchema()));
        pipeline.run();
    }

    private static TableSchema getTableSchema() {
        List<TableFieldSchema> fields = new ArrayList<>();
        fields.add(new TableFieldSchema().setName("year").setType("INTEGER"));
        fields.add(new TableFieldSchema().setName("month").setType("INTEGER"));
        fields.add(new TableFieldSchema().setName("day").setType("INTEGER"));
        fields.add(new TableFieldSchema().setName("wikimedia_project").setType("STRING"));
        fields.add(new TableFieldSchema().setName("language").setType("STRING"));
        fields.add(new TableFieldSchema().setName("title").setType("STRING"));
        fields.add(new TableFieldSchema().setName("views").setType("INTEGER"));
        return new TableSchema().setFields(fields);
    }

    public interface TemplateOptions extends DataflowPipelineOptions {
        @Description("GCS path of the file to read from")
        ValueProvider<String> getInputFile();

        void setInputFile(ValueProvider<String> value);
    }

    private static class WikiParDo extends DoFn<String, TableRow> {
        @ProcessElement
        public void processElement(ProcessContext c) throws Exception {
            String[] split = c.element().split(",");
            TableRow row = new TableRow();
            for (int i = 0; i < split.length; i++) {
                TableFieldSchema col = getTableSchema().getFields().get(i);
                row.set(col.getName(), split[i]);
            }
            c.output(row);
        }
    }
}
--项目=
--runner=数据流runner
--templateLocation=gs:///dataflow\u管道
--stagingLocation=gs:///jars
--tempLocation=gs:///tmp
程序代码如下:

 --project=<your_project_id>
 --runner=DataflowRunner
 --templateLocation=gs://<your_bucket>/dataflow_pipeline
 --stagingLocation=gs://<your_bucket>/jars
 --tempLocation=gs://<your_bucket>/tmp
public class TemplatePipeline {
    public static void main(String[] args) {
        PipelineOptionsFactory.register(TemplateOptions.class);
        TemplateOptions options = PipelineOptionsFactory
                .fromArgs(args)
                .withValidation()
                .as(TemplateOptions.class);
        Pipeline pipeline = Pipeline.create(options);
        pipeline.apply("READ", TextIO.read().from(options.getInputFile()).withCompressionType(TextIO.CompressionType.GZIP))
                .apply("TRANSFORM", ParDo.of(new WikiParDo()))
                .apply("WRITE", BigQueryIO.writeTableRows()
                        .to(String.format("%s:dataset_name.wiki_demo", options.getProject()))
                        .withCreateDisposition(CREATE_IF_NEEDED)
                        .withWriteDisposition(WRITE_TRUNCATE)
                        .withSchema(getTableSchema()));
        pipeline.run();
    }

    private static TableSchema getTableSchema() {
        List<TableFieldSchema> fields = new ArrayList<>();
        fields.add(new TableFieldSchema().setName("year").setType("INTEGER"));
        fields.add(new TableFieldSchema().setName("month").setType("INTEGER"));
        fields.add(new TableFieldSchema().setName("day").setType("INTEGER"));
        fields.add(new TableFieldSchema().setName("wikimedia_project").setType("STRING"));
        fields.add(new TableFieldSchema().setName("language").setType("STRING"));
        fields.add(new TableFieldSchema().setName("title").setType("STRING"));
        fields.add(new TableFieldSchema().setName("views").setType("INTEGER"));
        return new TableSchema().setFields(fields);
    }

    public interface TemplateOptions extends DataflowPipelineOptions {
        @Description("GCS path of the file to read from")
        ValueProvider<String> getInputFile();

        void setInputFile(ValueProvider<String> value);
    }

    private static class WikiParDo extends DoFn<String, TableRow> {
        @ProcessElement
        public void processElement(ProcessContext c) throws Exception {
            String[] split = c.element().split(",");
            TableRow row = new TableRow();
            for (int i = 0; i < split.length; i++) {
                TableFieldSchema col = getTableSchema().getFields().get(i);
                row.set(col.getName(), split[i]);
            }
            c.output(row);
        }
    }
}
公共类模板管道{
公共静态void main(字符串[]args){
PipelineOptionsFactory.register(TemplateOptions.class);
TemplateOptions=PipelineOptions工厂
.fromArgs(args)
.withValidation()
.as(TemplateOptions.class);
Pipeline=Pipeline.create(选项);
管道.apply(“READ”,TextIO.READ()。from(options.getInputFile())。with CompressionType(TextIO.CompressionType.GZIP))
.apply(“TRANSFORM”,ParDo.of(new WikiParDo()))
.apply(“WRITE”,BigQueryIO.writeTableRows()
.to(String.format(“%s:dataset\u name.wiki\u demo”,options.getProject()))
.withCreateDisposition(如果需要,则创建)
.带writedisposition(WRITE_TRUNCATE)
.withSchema(getTableSchema());
pipeline.run();
}
私有静态表模式getTableSchema(){
列表字段=新的ArrayList();
add(new TableFieldSchema().setName(“year”).setType(“INTEGER”);
add(new TableFieldSchema().setName(“month”).setType(“INTEGER”);
add(new TableFieldSchema().setName(“day”).setType(“INTEGER”);
fields.add(new TableFieldSchema().setName(“wikimedia_项目”).setType(“字符串”);
add(新的TableFieldSchema().setName(“语言”).setType(“字符串”));
add(新TableFieldSchema().setName(“title”).setType(“STRING”);
add(newtablefieldschema().setName(“视图”).setType(“整型”);
返回新的TableSchema().setFields(fields);
}
公共接口TemplateOptions扩展了DataflowPipelineOptions{
@说明(“要从中读取的文件的GCS路径”)
ValueProvider getInputFile();
作废setInputFile(ValueProvider值);
}
私有静态类WikiParDo扩展了DoFn{
@过程元素
public void processElement(ProcessContext c)引发异常{
字符串[]split=c.element().split(“,”);
TableRow行=新TableRow();
对于(int i=0;i
RuntimeValueProvider是一个极低级别的内部实现细节类,用户永远无法使用它;它具有公共可见性这一事实是Java可见性系统的一个不幸事故。“管道创建正在尝试验证值提供程序”是什么意思?我认为这不应该发生。你能把你的代码和你得到的错误完整打印出来吗?正如@jkff所说的,请发布你的代码。我假设您使用的是模板管道?我正在使用
2.1.0
作为模板的参数,没有任何问题。