我的简化工作看起来像这样:
tSetGlobalVar --->(onSubJobOK)---> tRunJob --->(onSubJobOK)---> tJava
myKey:"firstValue"
((String)globalMap.get("myKey")): "newValue"
还试过这个:
"myKey": "newValue"
System.out.println(((String)globalMap.get("myKey")));
实际输出:firstValue
预期输出:newValue
是否有其他方法可以修改子作业中全局变量的值并获取主作业中的更新值?
答案 0 :(得分:8)
您应该使用上下文变量而不是globalMap将数据传递给子作业。然后,使用子作业中的tBufferOutput将数据传递回父作业。
作为一个例子,这里是一个非常基本的设置,它接受一个id和一个日期并将它传递给一个子作业,它只是将它打印到控制台/日志,然后将一些数据传回给父作业。也只是打印到控制台/日志。
家长职位:
父作业中tFixedFlowInput中的数据如下:
注意你必须如何使用密钥值组合作为密钥,并将值传递给tContextLoad组件,然后创建一个由密钥命名并保持定义值的上下文变量。
在父作业中,我们设置id
和date
上下文变量,然后立即打印作业的当前上下文(包括刚刚设置的上下文变量)。
在此之后,我们使用tRunJob组件集调用子作业来传递整个上下文:
或者,您可以通过取消Transmit whole context
选项并明确定义要发送的上下文来指定传递给子作业的上下文变量。也可以在此定义上下文变量的值,但通常更有意义的是在作业的主流中生成上下文变量值,并将它们作为键值对传递给tContextLoad组件。
儿童工作:
在子作业中,我们只是通过将它们转储到带有tContextDump组件的tLogRow来打印已经发送的上下文,然后在这种情况下我们使用另一个tFixedFlowInput来硬编码一些数据:
然后我们将其传递给tBufferOutput组件,该组件允许我们在父作业中读回数据。
回到父作业,然后我们将tLogRow链接到带有主链接的tRunJob,并提供子作业的tBufferOutput中的模式。然后,这将打印子作业中的数据。
示例作业的输出是:
.----+----------.
|Parent Contexts|
|=---+---------=|
|key |value |
|=---+---------=|
|date|2014-10-30|
|id |12345 |
'----+----------'
.----+----------.
|Child Contexts |
|=---+---------=|
|key |value |
|=---+---------=|
|date|2014-10-30|
|id |12345 |
'----+----------'
.-----+----------.
|Child Data to be Passed to Parent|
|=----+---------=|
|id |date |
|=----+---------=|
|12346|2014-10-31|
'-----+----------'
.-----+----------.
|Output from Child1|
|=----+---------=|
|id |date |
|=----+---------=|
|12346|2014-10-31|
'-----+----------'
globalMap将数据存储在作业本身中,并且根本不与父作业或子作业共享,因此不能用于此目的。
答案 1 :(得分:4)
在Talend中你可以将上下文变量传递给子工具,它们就像标准的Java变量一样工作,所以如果你传递一些不可修改的东西(比如字符串或基本类型)你就不会得到任何改变,但是如果你传递了# 34;参考"您将更改对象的类型,您将看到子作业所做的更改,因为父作业仍保留对已更改对象的引用。
因此,您的问题的解决方案是简单地将globalMap从父作业传递到子作业,这样子项就可以读取和更改该图,父作业将看到任何更改。 您传递的地图将是与子作业的globalMap不同的地图,并且仅在您使用它的地方使用。
不幸的是,Talend只有一个"参考" type:Object类型,所以你需要传递任何东西作为对象anc将它转回到你将使用它的地方,但我认为这不是一个大问题。
以下是这份工作的图片: 跑着父亲
将地图传递给孩子
子项从contex变量中检索地图并使用地图