如何创建一个数据流模板不运行代码?



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

我所有的选项都是ValueProvider,但仍然,它试图在创建模板时执行代码,并给出一个错误。是否有任何方法我可以创建一个数据流模板而不执行代码?

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

是数据流模板的正确行为吗?

不传递所有参数的命令:

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的值赋给normal变量

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代替。文档可以在这里找到。

相关内容

最新更新