从U-SQL上的特定文件读取

时间:2018-09-23 13:33:00

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

我是U-SQL的新手,已经开始查询文件。根据我在文档中以及堆栈溢出中看到的说明,我编写了一个查询,用于从一组json文件中提取元数据,如下所示。

REFERENCE ASSEMBLY [Newtonsoft.Json];
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];

USING Microsoft.Analytics.Samples.Formats.Json;

DECLARE @InputFile string = "/test/{*}.json";
DECLARE @OutputFile string = "/metadata.csv";

@json =
EXTRACT
        id string,
        date DateTime,
        type string,
        uri = FILE.URI()
      , modified_date = FILE.MODIFIED()
      , created_date = FILE.CREATED()
      , file_sz = FILE.LENGTH()
FROM
    @InputFile
USING new JsonExtractor();

@json2 =
    SELECT 
    uri
    modified_date,
    created_date,
    file_sz
FROM @json;

@json3 =
    SELECT DISTINCT uri,
    modified_date,
    created_date,
    file_sz

    FROM @json2;
OUTPUT @json3
TO @OutputFile
USING Outputters.Csv(outputHeader:true,quoting:true);
DROP ASSEMBLY [Newtonsoft.Json];
DROP ASSEMBLY [Microsoft.Analytics.Samples.Formats];

这会生成所需的元数据(即使位置是相对的,我也会在Azure门户上运行此数据

我的问题是:

1)我们如何使用内部表/文件的一列(文件名的一列)中的值作为输入文件路径列表?

2)我们如何将新数据追加到现有文件中,并使用新文件列表更新元数据文件。

我的元数据如下:

uri           created_date       modified_date   file_sz
/…/abc.json      09-22-2018        09-23-2018       250
/…/del.json      09-24-2018        09-24-2018       126

期望的输出(如果可能)

@filespresent =
SELECT uri
FROM @metadata

DECLARE @Inputfile string = @filespresent

这样做的主要目的是每天获取一批新文件,并且我只想读取今天上传的文件。

文件名不包含日期,并且我可以提取日期信息的唯一方法是从文件内部。我在单独的查询中提取元数据,然后对从元数据文件中选择的文件运行主作业。

如果还有其他解决方法,也非常欢迎。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这是目前的限制。您可以为该功能投票here。这里也说相同的issue

解决该问题的唯一方法是使用带有注入如下所示外部变量的powershell运行u-sql脚本:

DECLARE EXTERNAL @InputFile string = "/Input/sample{n}.json";

如果尝试运行此命令,则会收到错误消息“行集变量不是标量变量” ...

REFERENCE ASSEMBLY [Newtonsoft.Json];
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];

USING Microsoft.Analytics.Samples.Formats.Json;

DECLARE @InputFile string = "/Input/sample4.json";
DECLARE @OutputFile1 string = "/Output/metadata1.csv";
DECLARE @OutputFile2 string = "/Output/metadata2.csv";
DECLARE @OutputFile3 string = "/Output/metadata3.csv";

@json1 =
EXTRACT
        // Json fields
        id string,   
        file string,
        // Virtual columns
        n string,
        uri = FILE.URI()
      , modified_date = FILE.MODIFIED()
      , created_date = FILE.CREATED()
      , file_sz = FILE.LENGTH()
FROM
    @InputFile // This file has a file set within
USING new JsonExtractor();

OUTPUT @json1
TO @OutputFile1
USING Outputters.Csv(outputHeader:true,quoting:true);

@json2 =
    SELECT 
    file
FROM @json1;

OUTPUT @json2
TO @OutputFile2
USING Outputters.Csv(outputHeader:true,quoting:true);

@json3 =
EXTRACT
        // Json fields
        id string,   
        file string,
        // Virtual columns
        n string,
        uri = FILE.URI()
      , modified_date = FILE.MODIFIED()
      , created_date = FILE.CREATED()
      , file_sz = FILE.LENGTH()
FROM
    @json2 // This is a rowset variable (with our fileset)
USING new JsonExtractor();

OUTPUT @json3
TO @OutputFile3
USING Outputters.Csv(outputHeader:true,quoting:true);

答案 1 :(得分:1)

您想要的功能(例如,从文件中读取路径并附加到现有文件)不可用。

附加到文件可以通过读取文件,合并新数据然后将结果写入同一文件来完成。

但是,通过查看您的情况**这样做的主要目的是每天获取一批新文件,并且我只想读取今天上传的文件。 **

您可以按照上述步骤操作EXTRACT,然后将过滤器放在created_datemodified_date列上,以仅选择针对特定日期创建或修改的文件。例如。 (键入stackoverflow),

DECLARE EXTERNAL @last_processed_modified_date = DateTime.Now();

@json = EXTRACT
    id string,
    date DateTime,
    type string,
    uri = FILE.URI()
  , modified_date = FILE.MODIFIED()
  , created_date = FILE.CREATED()
  , file_sz = FILE.LENGTH()
FROM @InputFile
USING new JsonExtractor();

@json = SELECT * FROM @json WHERE modified_date > @last_processed_modified_date;

…