繁体   English   中英

如何在不运行代码的情况下创建数据流模板?

[英]How to create a Dataflow Template without running code?

我正在创建一个数据流模板,如果我传递所有必需的参数,它可以完美运行,但我的用例是创建一个通用模板,我可以在运行时传递参数。

我所有的选项都是 ValueProvider 但它仍然在创建模板时尝试执行代码并且给出了错误。 有什么方法可以在不执行代码的情况下创建数据流模板吗?

当我使用 create template 命令和所有参数时,我也遇到了一个奇怪的问题,然后它成功创建了模板,但那时所有参数都在代码中硬编码,如果我在运行时传递新参数值,它不会改变模板的值。

它是 Dataflow 模板的正确行为吗?

不传递所有参数的命令:

mvn compile exec:java  -D"exec.mainClass"="org.example.Main" -D"exec.args"="--runner=DataflowRunner --project=<project>  --stagingLocation=gs://test-bucket/staging_4 --templateLocation=gs://test-bucket/templates/my_template  --region=asia-south1 "  -P dataflow-runner -X

多次设计我的代码后,我开始知道我在做什么错误。

我所知道的是,您的代码应该以这样一种方式设计,即除了项目 ID、阶段路径和模板路径之外,它不会要求任何值来生成图形。 如果有问题,请检查以下做法并进行相应的设计。

以下是创建自定义模板时应遵循的做法。

1 .将所有选项声明为ValueProvider ,以便在运行时计算它,模板创建过程将跳过它。

2 .不要将 ValueProvider 值分配给普通变量,如下所示。

String Query = options.getQuery().toString();
PCollection<TableRow> rows = p.apply("Read From Source", JdbcIO.<TableRow>read()
              .withQuery(Query)

3 .尝试将ValueProvider值直接传递给方法。 例如上面的代码片段应该如下所示

PCollection<TableRow> rows = p.apply("Read From Source", JdbcIO.<TableRow>read()
              .withQuery(options.getQuery())

4 .不要只在模板创建期间永远无法访问的任何一个特定代码块中使用选项。 如下例。

Boolean Check = false;

if (options.getA().isAccessible()){
   Check = true;
}   
if (Check == true){
  //Use of Options.getB().
}

在上述情况下,如果您在创建模板时未传递--a选项,则Check值将始终为false ,并且下面的特定代码块将无法执行。 如果我们没有在Check块中使用--b ,那么在创建模板选项b之后,模板将不知道它,如果您在运行时传递它,它将给出一个错误。

5 .如果您有需要操作传递的输入选项数据的用例,那么您应该使用NestedValueProvider而不是将ValueProvider转换为普通变量(例如 String)并操作数据。

例如,避免以下做法。

String Query = String.format("SELECT * FROM %s", options.getTableName().toString());
PCollection<TableRow> rows = p.apply("Read From Source", JdbcIO.<TableRow>read()
                  .withQuery(Query)

而是实现与以下相同的逻辑:

ValueProvider<String> Query = NestedValueProvider.of(options.getTableName(),
                                new SerializableFunction<String, String>() {
                                @Override
                             public String apply(TranslatorInput<String, String> input) 
                              {
                                return String.format("SELECT * FROM %s", input);;
                             }
                            });;
PCollection<TableRow> rows = p.apply("Read From Source", JdbcIO.<TableRow>read()
                  .withQuery(Query)

请改用FlexTemplates 可以在此处找到文档。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM