【问题标题】:Talend - generating n multiple rows from 1 rowTalend - 从 1 行生成 n 多行
【发布时间】:2014-10-14 15:53:04
【问题描述】:

背景:我正在使用 Talend 做一些非常常见的事情(我猜):从一个生成多行。例如:

ID | Name | DateFrom | DateTo

01 | Marco| 01/01/2014 | 04/01/2014

...可以拆分为:

new_ID | ID | Name | DateFrom | DateTo

01 | 01 | Marco | 01/01/2014 | 02/01/2014

02 | 01 | Marco | 02/01/2014 | 03/01/2014

03 | 01 | Marco | 03/01/2014 | 04/01/2014

输出行数是动态的,取决于原始行中的日期时间段。

问题:我该怎么做?也许使用 tSplitRow?我将使用 tJavaRow 检查这些时间段。有什么建议吗?

【问题讨论】:

  • 我假设这些是 dd-MM-yyyy 格式的日期?这实际上不是一件常见的事情,我正在努力想一个(好的)理由以这种方式规范化示例数据,但我对如何做到这一点有一些想法。
  • 日期格式是意大利语,这不是问题。我需要这样做,因为尽管我的目标数据库是原始记录,但它看起来像一个聚合记录。不过我很好奇你的想法:)

标签: java row etl talend


【解决方案1】:

扩展 Balazs Gunics 给出的答案

您的第一部分是计算一行将成为的行数,使用日期差异函数在 to 和 from 日期上很容易


第 2 部分是将该值传递给 tFlowToIterate,并使用 tJavaFlex 获取它,该 tJavaFlex 将在其开始代码中使用它来控制 for 循环:

tJavaFlex 开始:

int currentId = (Integer)globalMap.get("out1.id");
String currentName = (String)globalMap.get("out1.name");
Long iterations = (Long)globalMap.get("out1.iterations");
Date dateFrom = (java.util.Date)globalMap.get("out1.dateFrom");

for(int i=0; i<((Long)globalMap.get("out1.iterations")); i++) { 

主要

  row2.id = currentId;
  row2.name = currentName;
  row2.dateFrom = TalendDate.addDate(dateFrom, i, "dd");
  row2.dateTo = TalendDate.addDate(dateFrom, i+1, "dd");

结束

}

和样本输出:

1|Marco|01-01-2014|02-01-2014
1|Marco|02-01-2014|03-01-2014
1|Marco|03-01-2014|04-01-2014
2|Polo|01-01-2014|02-01-2014
2|Polo|02-01-2014|03-01-2014
2|Polo|03-01-2014|04-01-2014
2|Polo|04-01-2014|05-01-2014
2|Polo|05-01-2014|06-01-2014
2|Polo|06-01-2014|07-01-2014
2|Polo|07-01-2014|08-01-2014
2|Polo|08-01-2014|09-01-2014
2|Polo|09-01-2014|10-01-2014
2|Polo|10-01-2014|11-01-2014
2|Polo|11-01-2014|12-01-2014
2|Polo|12-01-2014|13-01-2014
2|Polo|13-01-2014|14-01-2014
2|Polo|14-01-2014|15-01-2014
2|Polo|15-01-2014|16-01-2014
2|Polo|16-01-2014|17-01-2014
2|Polo|17-01-2014|18-01-2014
2|Polo|18-01-2014|19-01-2014
2|Polo|19-01-2014|20-01-2014
2|Polo|20-01-2014|21-01-2014
2|Polo|21-01-2014|22-01-2014
2|Polo|22-01-2014|23-01-2014
2|Polo|23-01-2014|24-01-2014
2|Polo|24-01-2014|25-01-2014
2|Polo|25-01-2014|26-01-2014
2|Polo|26-01-2014|27-01-2014
2|Polo|27-01-2014|28-01-2014
2|Polo|28-01-2014|29-01-2014
2|Polo|29-01-2014|30-01-2014
2|Polo|30-01-2014|31-01-2014
2|Polo|31-01-2014|01-02-2014

【讨论】:

  • 是的,这正是我的思考过程。做得很好,我喜欢使用屏幕截图来进一步解释您的部分答案。
【解决方案2】:

您可以使用 tJavaFlex 来执行此操作。

如果您有少量的列,则 tFlowToIterate -> tJavaFlex 选项可能没问题。

在开始部分,您可以开始迭代,在主要部分中,您可以为输出模式分配值。如果您将输出命名为 row6,则:

row6.id = (String)globalMap.get("id");

等等。

【讨论】:

  • 你是对的,它可能需要一个 tJavaFlex 来做到这一点,但你应该在这个答案中添加更多细节,因为它目前不能解决 OP 的问题。
【解决方案3】:

我来到这里是因为我想将所有 context 参数添加到 Excel 数据表中。因此,当您采用 0 行输入时,下面的解决方案有效,但可以调整为为输入中的每一行生成几行。

设计实际上是直截了当的:

tJava –trigger-on-OK→ tFileInputDelimited  → tDoSomethingOnRowSet
  ↓                          ↑
[write into a CSV]     [read the CSV]

这是 tJava 中可用的代码结构。

try {
  StringBuffer wad = new  StringBuffer();
  
  wad.append("Key;Nub"); // Header
  context.stringPropertyNames().forEach(
    key -> wad.
      append(System.getProperty("line.separator")).
      append(key + ";" + context.getProperty(key) ) 
  );
  
  // Here context.metadata contains the path to the CSV file
  FileWriter output = new FileWriter(context.metadata);
  output.write(wad.toString());
  output.close();
} catch (IOException mess) {
  System.out.println("An error occurred.");
  mess.printStackTrace();
}

当然,如果您有一组行作为输入,您可以调整流程以使用 tJavaRow 而不是 tJava。

您可能更喜欢使用 Excel 文件作为磁盘缓冲区,但处理这种文件格式至少在第一次没有在 Talend 中配置 Java 库时需要做更多的工作。如果您仍然选择这样做,Apache POI 可能会对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 2020-09-17
    • 2014-11-30
    相关资源
    最近更新 更多