【问题标题】:How to upload JSON file to Azure Data Lake table如何将 JSON 文件上传到 Azure Data Lake 表
【发布时间】:2023-03-26 06:10:01
【问题描述】:

我是 ADL 和 JSON 文件的新手。我正在尝试将 JSON 文件加载到 ADL 表中。

我的 JSON 文件结构是

{ABCD:{Time:"", Date:"", ProcessingTime:"", ProcessName:""}},
{ABCD:{Date:"", ProcessingTime:"", ProcessName:""}},
{ABCD:{ProcessingTime:"", ProcessName:""}},
{ABCD:{Time:"", Date:"", ProcessingTime:"", ProcessName:""}},

我的表包含所有 4 列(时间、数据、处理时间和进程名称)。

首先,我尝试在将其写入表之前使用 USQL 语句将其写入 CSV 文件。但是,生成的 CSV 输出包含所有空白记录。

感谢任何帮助。我也可以通过 ADF 执行此操作吗?我想把它作为一个预定的工作。

以下是我用来编写 CSV 文件的 USQL 代码。

CREATE ASSEMBLY IF NOT EXISTS [Newtonsoft.Json] FROM 
"C:/Test/Assemblies/Newtonsoft.Json.dll";
CREATE ASSEMBLY IF NOT EXISTS [Microsoft.Analytics.Samples.Formats] FROM 
"C:/ADL/Assemblies/Microsoft.Analytics.Samples.Formats.dll";

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

USING Microsoft.Analytics.Samples.Formats.Json;

DECLARE @path string = @"C:\Test\";
DECLARE @input string = @path + @"sample_data1.json";
DECLARE @to string = @path + @"output.csv";

@jsonFile =
 EXTRACT
Time string,
Date string,
ProcessingTime string,
ProcessName string 
FROM @input
USING new JsonExtractor();

OUTPUT @jsonFile
TO @to
USING Outputters.Csv();

干杯!

【问题讨论】:

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


    【解决方案1】:

    该文件不包含有效的 Json 文档。每行似乎是一个 Json 对象。 ADL 可以处理每行一个对象的 Json 文件,但每个 Json 对象都应该写在一个新行上,而不需要任何额外的分隔符,因此您应该删除每行末尾的 ,。像这样:

    {"ABCD":{"Time":"", "Date":"", "ProcessingTime":"", "ProcessName":""}}
    {"ABCD":{"Date":"", "ProcessingTime":"", "ProcessName":""}}
    {"ABCD":{"ProcessingTime":"", "ProcessName":""}}
    {"ABCD":{"Time":"", "Date":"", "ProcessingTime":"", "ProcessName":""}}
    

    那么你不能直接使用JsonExtractor,你将不得不使用文本提取器提取所有单独的Json行,然后使用JsonTuple方法将其转换为Json:

    CREATE ASSEMBLY IF NOT EXISTS [Newtonsoft.Json] FROM 
    "C:/Test/Assemblies/Newtonsoft.Json.dll";
    CREATE ASSEMBLY IF NOT EXISTS [Microsoft.Analytics.Samples.Formats] FROM 
    "C:/ADL/Assemblies/Microsoft.Analytics.Samples.Formats.dll";
    
    REFERENCE ASSEMBLY [Newtonsoft.Json];
    REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];
    
    USING Microsoft.Analytics.Samples.Formats.Json;
    
    DECLARE @path string = @"C:\Test\";
    DECLARE @input string = @path + @"sample_data1.json";
    DECLARE @to string = @path + @"output.csv";
    
    @RawExtract  = EXTRACT [RawString] string
    FROM @input 
    USING Extractors.Text(delimiter:'\b', quoting : false);
    
    @ParsedJSONLines = SELECT JsonFunctions.JsonTuple([RawString]) AS JSONLine
        FROM @RawExtract;
    
    @jsonObjects =
    SELECT JsonFunctions.JsonTuple(JSONLine["ABCD"]) AS Abcd
    FROM @ParsedJSONLines;
    
     @result =
    SELECT 
        Abcd["Time"] AS Time,
        Abcd["Date"] AS Date,
        Abcd["ProcessingTime"] AS ProcessingTime,
        Abcd["ProcessName"] AS ProcessName
    FROM @jsonObjects;
    
    OUTPUT @result
    TO @to
    USING Outputters.Csv();
    

    【讨论】:

    • 谢谢彼得!删除了 Json 对象之间的逗号并按照上面的建议更新了代码,但是代码失败并出现“加载 jarray 时内容意外结束”错误。谷歌搜索,但无法诊断错误。非常感谢任何指导。
    • @Rmani 经过进一步检查,我注意到 Json 输入仍然无效。我已经更新了答案中的示例输入。然后我注意到在运行作业时显然不能使用所有大写标识符,所以我在脚本(l.23)中将AS ADBC 更改为AS Abcd。我已经用我的示例输入对其进行了测试,没有出现错误。错误是否指示任何行?你使用示例 json 还是其他文件?
    • 再次感谢彼得!能够创建 CSV 文件,有没有办法通过 USQL 删除 JSON 对象之间的逗号并插入到 Azure 表中?我一直在谷歌上搜索这些问题的答案,但找不到任何相关信息。
    • 那么,我是否正确地说您希望每一行都作为 azure 表存储中的一行,而 csv 行中的每个字段值都应该是 azure 表存储中的一列?
    • 你是正确的!这就是我到目前为止没有运气的事情:-(
    【解决方案2】:

    根据您在 cmets 中对 Peter 回复的补充说明:

    首先,您不能直接使用 U-SQL 将数据插入 Azure 表存储。您必须使用 Azure 数据工厂将清理/转换后的文件从 ADLS 移动到 Azure 表。

    我在上面看到的问题是 JSON 文档还包含 , 来分隔它们的属性。因此,一些简单的方法(例如使用 , 作为行或列分隔符)会失败。您可以做的是编写类似(替换上述脚本中的 EXTRACT)

    @RawExtract  =
      EXTRACT [RawString] string
      FROM @input 
      USING Extractors.Text(delimiter:'\b', quoting : false);
    
    @RawExtract = SELECT RawString.TrimEnd(',') AS RawString FROM @RawExtract; 
    

    删除行的最后一个字符(假设它是 a ,或者您可以编写一些其他 C# 表达式来查找最后一个逗号的位置并使用 String.Substring 而不是 String.TrimEnd)。这假设每个 JSON 文档都适合一行并适合 128kB 的字符串数据类型。

    或者,您必须编写一个完全理解您的文件格式的自定义提取器,并在将提取器 UDO 属性 atomicFileProcessing 设置为 true 的情况下在 input.baseStream 级别进行操作。从http://usql.io 链接的 GitHub 站点上提供了一些示例提取器,它们可能对此有所帮助。但我建议先试试上面的建议。

    干杯 迈克尔

    PS:U-SQL 中可以有全大写标识符,但需要引用,例如AS [ABCD]

    【讨论】:

    • 谢谢,迈克尔。我能够删除逗号并通过脚本创建 CSV 文件。我了解 U-SQL 不能用于将数据插入 Azure 表存储,将尝试使用 ADF。再次感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    相关资源
    最近更新 更多