U-SQL在使用Text Extractor后忽略在JsonFunctions.JsonTuple()中导致JSON异常的行

问题描述 投票:1回答:2

我正在尝试将JSON文件转换为csv,提取一些感兴趣的特定键/值。我有大文本文件(> 100万行),其中每行是一个JSON对象。实际的结构是嵌套的并包含数组,但对于这个问题它并不重要。

示例文件:

{"param1": val00, "param2": val01}
{"param1": val10, "param2": val11}
...
{"param1": valn0, "param2": valn1}

我正在使用以下代码与Text Extractor将每一行转换为JSON对象,然后使用JsonFunctions.JsonTuple()解析JSON对象

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

USING Microsoft.Analytics.Samples.Formats.Json;

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

@json =
    SELECT JsonFunctions.JsonTuple(RawString, "..*") AS RootObject
    FROM @RawExtract;

我遇到问题,因为至少有一行是腐败的,如下所示:

{"param1": val00, "param2"{"param1": val10, "param2": val11}
...
{"param1": valn0, "param2": valn1}

这些是我收到的错误消息

VertexFailedFast:顶点失败并出现故障快速错误E_RUNTIME_USER_EXPRESSIONEVALUATION评估表达式时出错Microsoft.Analytics.Samples.Formats.Json.JsonFunctions.JsonTuple(RawString,“.. *”)用户表达式的内部异常:解析值后出现意外字符遇到了:{。

====在Newtonsoft.Json.Json.JarseTextReader()中的Newtonsoft.Json.JsonTextReader.ParsePostValue(布尔值ignoreComments)中捕获异常Newtonsoft.Json.JsonReaderException,Newtonsoft.Json.Linq.JContainer.ReadContentFrom(JsonReader r,JsonLoadSettings设置) Newtonsoft.Json.Linq.JContainer.ReadTokenFrom(JsonReader reader,JsonLoadSettings options)at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader,JsonLoadSettings settings)at Newtonsoft.Json.Linq.JToken.ReadFrom(JsonReader reader,JsonLoadSettings settings) )在Microsoft.Analytics.Samples的Microsoft.Analytics.Samples.Formats.Json.JsonFunctions.JsonTuple [T](String json,String [] paths)中的Newtonsoft.Json.Linq.JToken.Parse(String json,JsonLoadSettings settings) .Formats.Json.JsonFunctions.JsonTuple(String json,String [] paths)at _Scope_Generated_Classes_.SqlFilterTransformer_13.Process(IRow inRow,IUpdatableRow outRow)在d:\ data \ yarnnm \ local \ usercache \ 45905a29-60cf-4dd2-bf9c- c2b31bedea60 \应用程序缓存\ application_154620784205 9_5159256 \ container_e346_1546207842059_5159256_01_000001 \ wd__ScopeCodeGen __。dll.cs:第233行

我不介意失去几行。我看到,对于提取器,我可以使用silent: true来忽略坏行。 JsonFunctions.JsonTuple()解析函数有类似的选项吗?

c# json azure azure-data-lake u-sql
2个回答
1
投票

可以在U-SQL脚本中创建一个try-catch块,以避免在JsonReaderException上崩溃。

试试块

// Ignore rows with invalid JSON formattting
DECLARE @TryParseJson Func<string, SqlMap<string, string>> = (RawString)=>{
    try 
    {
        return JsonFunctions.JsonTuple(RawString, "..*");
    }
    catch (Newtonsoft.Json.JsonReaderException e)
    {
        return null;  // Consider returning empty SqlMap<string, string> instead
    }
};

提取并解析JSON

每行包含一个JSON字符串

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

@json =
    SELECT @TryParseJson(RawString) AS RootObject
    FROM @RawExtract;

忽略具有无效JSON的行(空值)

@result =
    SELECT RootObject["id"] AS Id
         , RootObject["status"] AS Status
         , RootObject["time"] AS Time
    FROM @json
    WHERE RootObject != null;  // Ignore invalid JSON

0
投票

JsonTuple没有类似的选项。

我看到两个选项来处理这个问题。

  1. 创建代码以捕获错误
  2. 编写自己的JsonFunctions版本来处理错误。

源代码在这里:https://github.com/Azure/usql/blob/master/Examples/DataFormats/Microsoft.Analytics.Samples.Formats/Json/JsonFunctions.cs

© www.soinside.com 2019 - 2024. All rights reserved.