ADLA工作:根据行内容写入不同的文件

时间:2017-12-11 20:43:12

标签: azure azure-data-lake u-sql

我有一个固定宽度文本文件的BUNCH,其中包含多个交易类型,只有3个我关心的(121,122,124)。

示例文件:

  

D1034216的 121 00188300000300000000012N000002000001000032021420170012260214201700122600000000059500000300001025798   D1034216 122 00188300000300000000011000000000010000012053700028200004017000000010240000010000011NNYNY000001000003N0000000000 00   D1034216 124 001883000003000000000110000000000300000100000000000CS00000100000001200000033NN0 00000001200

所以我需要做的是从这些文件中逐行读取并查找在startIndex = 9和length = 3时具有121,122或124的那些文件。

需要根据我拥有的数据字典解析每一行,并且需要按事务类型将输出分组为三个不同的文件。

我有一个有效的过程,但效率非常低,基本上每次读取3次。我的代码是这样的:

@121 = EXTRACT
    col1 string,
    col2 string,
    col3 string //ect...
FROM inputFile
USING new MyCustomExtractor(
    new SQL.MAP<string, string> {
        {"col1","2"},
        {"col2","6"},
        {"col3","3"} //ect...
    };
);
OUTPUT @121
TO 121.csv
USING Outputters.Csv();

我有122和124的相同代码。我的自定义提取器获取SQL MAP并返回解析的行并跳过所有不包含我正在寻找的事务类型的行。

这种方法也意味着我要在文件中的所有行中运行3次。显然这不是那么有效。

我正在寻找的是一种高效的读取线路的高级概念,确定它是否是我关心的事务,然后输出到正确的文件。

提前致谢。

2 个答案:

答案 0 :(得分:1)

如何使用String数据类型的Substring方法尽早提取事务类型?然后你可以用它做一些工作,过滤等。一个简单的例子:

// Test data
@input = SELECT *
     FROM (
        VALUES
        ( "D103421612100188300000300000000012N000002000001000032021420170012260214201700122600000000059500000300001025798" ), 
        ( "D103421612200188300000300000000011000000000010000012053700028200004017000000010240000010000011NNYNY000001000003N0000000000 00" ),
        ( "D1034216124001883000003000000000110000000000300000100000000000CS00000100000001200000033NN0 00000001200" ),
        ( "D1034216999 0000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000" )
     ) AS x ( rawData );


// Pull out the transaction type
@working =
    SELECT rawData.Substring(8,3) AS transactionType,
           rawData
    FROM @input;


// !!TODO do some other work here
@output =
    SELECT *
    FROM @working
    WHERE transactionType IN ("121", "122", "124");   //NB Note the case-sensitive IN clause


OUTPUT @output TO "/output/output.csv"
USING Outputters.Csv();

答案 1 :(得分:1)

截至今天,没有特定的U-SQL函数可以动态定义元组的输出位置。

wBob介绍了一种潜在解决方法。我将通过以下方式扩展解决方案以满足您的需求:

  1. 阅读整个文件,添加一个新列,帮助您识别交易类型。
  2. 使用上一步中创建的列上具有特定事务类型(121,122,124)的WHERE语句创建3个行集(每个文件一个)。
  3. 将上一步中创建的每个行集输出到各自的文件中。
  4. 如果您有更多反馈或需求,请随时在我们的UserVoice网站上创建一个项目(并为他人投票):https://feedback.azure.com/forums/327234-data-lake。谢谢!