web-dev-qa-db-ja.com

Azure SqlデータベースへのAzure Data Factoryの複雑なJSONソース(ネストされた配列)?

Azure BLOBストレージに定期的にアップロードされるJSONソースドキュメントがあります。お客様は、Azure Data Factoryを使用してこの入力を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
Emrikol

以前は、次のようにすることができます blog と私の前のケース: コピーデータでソースからシンクにデータを失う Blob Storage DatasetでCross-apply nested JSON arrayオプションを設定します。しかし、今は消えます。

代わりに、 コレクション参照 がコピーアクティビティの配列項目スキーママッピングに適用されます。

enter image description here

しかし、私のテストに基づくと、スキーマでフラット化できる配列は1つだけです。複数の配列を参照できます。配列内のすべての要素を含む1つの行として返されます。ただし、各要素を個別の行として返すことができる配列は1つだけです。これは、jsonPath settingsの現在の制限です。

enter image description here

回避策として、最初にネストされたオブジェクトを含むjsonファイルをLogic Appを使用してCSVファイルに変換し、次にCSVファイルをAzure Data Factoryの入力として使用できます。 Logic Appを使用してjsonファイル内のネストされたオブジェクトをCSVに変換する方法を理解するには、この doc を参照してください。確かに、SPは@GregGallowayのコメントで言及されています)など、SQLデータベース側でいくつかの作業を行うこともできます。


要約すると、残念ながら、「コレクション参照」は、@ Emrikolに適していない配列構造の1レベル下でのみ機能します。最後に、@ EmrikolはData Factoryを放棄し、仕事用のアプリを構築しました。

0
Jay Gong

Azure SQL Databaseには、JSONを細断処理す​​る [〜#〜] openjson [〜#〜] や、JSONからスカラー値を返す JSON_VALUE など、JSONを細かく処理する機能があります。アーキテクチャにAzure SQL DBが既にあるので、コンポーネントを追加するのではなく、それを使用するのが理にかなっています。

では、Data Factoryを使用してJSONをAzure SQL DBのテーブルに挿入し、ストアドプロシージャタスクを呼び出してそれを細断するELTパターンを採用しないのはなぜですか?あなたの例に基づくいくつかのサンプルSQL:

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;

ご覧のとおり、私はCROSS APPLY複数のレベルをナビゲートします。私の結果:

My results

0
wBob