2017-08-15 175 views
1

我是ADL的新手& JSON文件。我正在尝试将JSON文件加载到ADL表中。如何将JSON文件上传到Azure Data Lake表

我的JSON文件结构

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

我的表有所有的4列(时间,数据,ProcessingTime,& ProcessName)。

首先,我在使用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(); 

干杯!

回答

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(); 
+0

谢谢彼得!删除了Json对象之间的逗号并按照上面的建议更新了代码,但是代码失败,出现“加载jarray时意外的内容结束”错误。使用Google搜索,但无法诊断错误。任何指导非常感谢。 – Rmani

+0

@Rmani进一步检查我注意到Json输入仍然无效。我已经更新了答案中的示例输入。然后我注意到在运行这个工作时显然你不能使用所有的大写标识符,所以我在脚本(l.23)中将'AS ADBC'改为'AS Abcd'。我用我的示例输入测试了它,并没有发现错误。错误是否显示任何行?你是否使用示例json或其他文件? –

+0

再次感谢彼得!能够创建CSV文件,有没有办法通过USQL删除JSON对象之间的逗号并插入到Azure表中?我一直在Google上寻找答案,但找不到任何相关信息。 – Rmani

0

根据您对Peter的回复的评论中的额外说明:

首先,您不能直接使用U-SQL将数据插入到Azure表存储中。您将不得不使用Azure Data Factory将已清理/已转换的文件从ADLS移至Azure Table。

我在上面看到的问题是,JSON文档也包含,以分离它们的属性。所以一些简单的方法,如使用行或列分隔符将会失败。你可以做的是写类似(替换上面的脚本提取物)

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

@RawExtract = SELECT RawString.TrimEnd(',') AS RawString FROM @RawExtract; 

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

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

干杯 迈克尔

PS:你可以在U型SQL全部大写标识,但你需要说出来了,例如,AS [ABCD]

+1

谢谢,迈克尔。我能够通过脚本删除逗号并创建CSV文件。我知道U-SQL不能用于将数据插入到Azure中表格存储,将尝试与ADF。再次感谢您的帮助! – Rmani

相关问题