将Azure数据工厂的复杂JSON源(嵌套数组)发送到Azure Sql数据库?

时间:2020-02-03 09:53:09

标签: azure azure-data-factory

我有一个JSON源文档,该文档将定期上传到Azure blob存储。客户希望使用Azure数据工厂将此输入写入Azure Sql数据库。但是,JSON具有许多嵌套数组,因此非常复杂,到目前为止,我还无法找到一种使文档扁平化的方法。也许不支持/可能吗?

[
{
"ActivityId": 1,
    "Header": {},
    "Body": [{
        "1stSubArray": [{
            "Id": 456,
            "2ndSubArray": [{
                "Id": "abc",
                "Descript": "text",
                "3rdSubArray": [{
                    "Id": "def",
                    "morefields": "text"
                },
                {
                    "Id": "ghi",
                    "morefields": "sample"
                }]
            }]
        }]
    }]
}
]

我需要弄平它:

ActivityId, Id, Id, Descript, Id, morefields
1, 456, abc, text1, def, text
1, 456, abc, text2, ghi, sample
1, 456, xyz, text3, jkl, textother
1, 456, xyz, text4, mno, moretext 

每个ActivityId可能有8条以上的固定记录。有没有看到这种情况并找到使用Azure Data Factory复制数据解决方法的人?

2 个答案:

答案 0 :(得分:1)

Azure SQL数据库具有一些强大的JSON分解功能,其中包括OPENJSON可以分解JSON,以及JSON_VALUE可以从JSON返回标量值。由于您已经在体系结构中拥有Azure SQL DB,因此使用它而不是添加其他组件是很有意义的。

那么,为什么不采用ELT模式,在这种模式下,您可以使用Data Factory将JSON插入Azure SQL DB中的表中,然后调用存储过程任务来粉碎它呢?一些基于您的示例的示例SQL:

linux:
    if [ -a /etc/os-release ]; then . /etc/os-release OS=$NAME VER=$VERSION_ID fi;
    #<------------------------- maybe add more???

如您所见,我使用DECLARE @json NVARCHAR(MAX) = '[ { "ActivityId": 1, "Header": {}, "Body": [ { "1stSubArray": [ { "Id": 456, "2ndSubArray": [ { "Id": "abc", "Descript": "text", "3rdSubArray": [ { "Id": "def", "morefields": "text" }, { "Id": "ghi", "morefields": "sample" } ] }, { "Id": "xyz", "Descript": "text", "3rdSubArray": [ { "Id": "jkl", "morefields": "textother" }, { "Id": "mno", "morefields": "moretext" } ] } ] } ] } ] } ]' --SELECT @json j -- INSERT INTO yourTable ( ... SELECT JSON_VALUE ( j.[value], '$.ActivityId' ) AS ActivityId, JSON_VALUE ( a1.[value], '$.Id' ) AS Id1, JSON_VALUE ( a2.[value], '$.Id' ) AS Id2, JSON_VALUE ( a2.[value], '$.Descript' ) AS Descript, JSON_VALUE ( a3.[value], '$.Id' ) AS Id3, JSON_VALUE ( a3.[value], '$.morefields' ) AS morefields FROM OPENJSON( @json ) j CROSS APPLY OPENJSON ( j.[value], '$."Body"' ) AS m CROSS APPLY OPENJSON ( m.[value], '$."1stSubArray"' ) AS a1 CROSS APPLY OPENJSON ( a1.[value], '$."2ndSubArray"' ) AS a2 CROSS APPLY OPENJSON ( a2.[value], '$."3rdSubArray"' ) AS a3; 浏览多个级别。我的结果:

My results

答案 1 :(得分:0)

过去,您可以遵循此blog和我以前的情况:Loosing data from Source to Sink in Copy Data在Blob存储数据集中设置Cross-apply nested JSON array选项。但是,它现在消失了。

相反,Collection Reference适用于复制活动中的数组项架构映射。

enter image description here

但是根据我的测试,架构中只能将一个数组展平。可以引用多个数组-返回为包含该数组中所有元素的一行。但是,只有一个数组可以将其每个元素作为单独的行返回。这是jsonPath settings的当前限制。

enter image description here

作为解决方法,您可以首先使用Logic App将带有嵌套对象的json文件转换为CSV文件,然后可以使用CSV文件作为Azure数据工厂的输入。请参阅此doc,以了解如何使用Logic App将json文件中的嵌套对象转换为CSV。当然,您也可以在sql数据库方面做出一些努力,例如@GregGalloway的注释中提到的SP。


仅出于摘要目的,不幸的是,“集合引用”仅在不适用于@Emrikol的数组结构中向下一级使用。最终,@ Emrikol放弃了Data Factory并为其创建了一个应用程序。