Transform complex JSON structures from CosmosDB to SQL DB with Azure Data Factory

Published Mar 10 2020 03:54 PM 4,571 Views
Microsoft

 

  1. Start with this JSON collection in ADF based on this Orders dataset. This data has orders from Northwind with order header and order details embedded in a single document per order.
  2. You can load it into CosmosDB as the video above explains, or start with a JSON file in Blob or ADLS as your source in ADF data flow.
  3. In ADF Data Flow, add a Flatten transformation following your source and choose "Details" as the array to unroll. Leave unroll root as empty/default.
  4. This will produce a new structure called "Details". Use a Derived Column next to add a new property to that struct called "totalAmount".
  5. In the Derived Column, choose the root level "Details" field. Click on Expression Builder.
  6. In the middle Functions pane, select the icon next to "Details" to add the expression structure automatically.
  7. in the left-side "Input Schema" pane, click the plus sign on the bottom of the structure and add a new column. Call it "totalAmount"
    h2h.png
  8. The formula for totalAmount is 
    toString(round(toInteger(details.quantity)*toInteger(details.unitPrice),2),'###.##')​
  9. Now you're ready to sink your data to an Azure SQL DB table. In the Sink, set the dataset to Azure SQL DB.
  10.  Set the mapping to look like this:
     h2h2.png
  11. You can leave all of the root-level k/v fields set as they are by default. Choose the individual properties from each structure that you wish to map to a database table column.

The full online documentation for this ADF transformation can be found here.

 

You can download this sample pipeline demo using the ADF Pipeline Template here. Install it in your factory by going to New > Pipeline from template > import template.

 

 

2 Comments
%3CLINGO-SUB%20id%3D%22lingo-sub-1221106%22%20slang%3D%22en-US%22%3ETransform%20complex%20JSON%20structures%20from%20CosmosDB%20to%20SQL%20DB%20with%20Azure%20Data%20Factory%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1221106%22%20slang%3D%22en-US%22%3E%3CP%3E%3C%2FP%3E%3CDIV%20class%3D%22video-embed-center%20video-embed%22%3E%3CIFRAME%20class%3D%22embedly-embed%22%20src%3D%22https%3A%2F%2Fcdn.embedly.com%2Fwidgets%2Fmedia.html%3Fsrc%3Dhttps%253A%252F%252Fwww.youtube.com%252Fembed%252FVY2tFQJoAXE%253Ffeature%253Doembed%26amp%3Bdisplay_name%3DYouTube%26amp%3Burl%3Dhttps%253A%252F%252Fwww.youtube.com%252Fwatch%253Fv%253DVY2tFQJoAXE%26amp%3Bimage%3Dhttps%253A%252F%252Fi.ytimg.com%252Fvi%252FVY2tFQJoAXE%252Fhqdefault.jpg%26amp%3Bkey%3Db0d40caa4f094c68be7c29880b16f56e%26amp%3Btype%3Dtext%252Fhtml%26amp%3Bschema%3Dyoutube%22%20width%3D%22400%22%20height%3D%22225%22%20scrolling%3D%22no%22%20title%3D%22YouTube%20embed%22%20frameborder%3D%220%22%20allow%3D%22autoplay%3B%20fullscreen%22%20allowfullscreen%3D%22true%22%3E%3C%2FIFRAME%3E%3C%2FDIV%3E%3CP%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3EStart%20with%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fkromerm%2Fadfdataflowdocs%2Fblob%2Fmaster%2Fsampledata%2Forders.json%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%22%3Ethis%3C%2FA%3E%20JSON%20collection%20in%20ADF%20based%20on%20this%20Orders%20dataset.%20This%20data%20has%20orders%20from%20Northwind%20with%20order%20header%20and%20order%20details%20embedded%20in%20a%20single%20document%20per%20order.%3C%2FLI%3E%0A%3CLI%3EYou%20can%20load%20it%20into%20CosmosDB%20as%20the%20video%20above%20explains%2C%20or%20start%20with%20a%20JSON%20file%20in%20Blob%20or%20ADLS%20as%20your%20source%20in%20ADF%20data%20flow.%3C%2FLI%3E%0A%3CLI%3EIn%20ADF%20Data%20Flow%2C%20add%20a%20Flatten%20transformation%20following%20your%20source%20and%20choose%20%22Details%22%20as%20the%20array%20to%20unroll.%20Leave%20unroll%20root%20as%20empty%2Fdefault.%3C%2FLI%3E%0A%3CLI%3EThis%20will%20produce%20a%20new%20structure%20called%20%22Details%22.%20Use%20a%20Derived%20Column%20next%20to%20add%20a%20new%20property%20to%20that%20struct%20called%20%22totalAmount%22.%3C%2FLI%3E%0A%3CLI%3EIn%20the%20Derived%20Column%2C%20choose%20the%20root%20level%20%22Details%22%20field.%20Click%20on%20Expression%20Builder.%3C%2FLI%3E%0A%3CLI%3EIn%20the%20middle%20Functions%20pane%2C%20select%20the%20icon%20next%20to%20%22Details%22%20to%20add%20the%20expression%20structure%20automatically.%3C%2FLI%3E%0A%3CLI%3Ein%20the%20left-side%20%22Input%20Schema%22%20pane%2C%20click%20the%20plus%20sign%20on%20the%20bottom%20of%20the%20structure%20and%20add%20a%20new%20column.%20Call%20it%20%22totalAmount%22%3CBR%20%2F%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22h2h.png%22%20style%3D%22width%3A%20364px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F176272iA926FD688F73761F%2Fimage-dimensions%2F364x225%3Fv%3D1.0%22%20width%3D%22364%22%20height%3D%22225%22%20title%3D%22h2h.png%22%20alt%3D%22h2h.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3EThe%20formula%20for%20totalAmount%20is%26nbsp%3B%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3EtoString(round(toInteger(details.quantity)*toInteger(details.unitPrice)%2C2)%2C'%23%23%23.%23%23')%E2%80%8B%3C%2FCODE%3E%3C%2FPRE%3E%3C%2FLI%3E%0A%3CLI%3ENow%20you're%20ready%20to%20sink%20your%20data%20to%20an%20Azure%20SQL%20DB%20table.%20In%20the%20Sink%2C%20set%20the%20dataset%20to%20Azure%20SQL%20DB.%3C%2FLI%3E%0A%3CLI%3E%26nbsp%3BSet%20the%20mapping%20to%20look%20like%20this%3A%3CBR%20%2F%3E%26nbsp%3B%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22h2h2.png%22%20style%3D%22width%3A%20307px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F176274iD522F7C355039C98%2Fimage-dimensions%2F307x100%3Fv%3D1.0%22%20width%3D%22307%22%20height%3D%22100%22%20title%3D%22h2h2.png%22%20alt%3D%22h2h2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3EYou%20can%20leave%20all%20of%20the%20root-level%20k%2Fv%20fields%20set%20as%20they%20are%20by%20default.%20Choose%20the%20individual%20properties%20from%20each%20structure%20that%20you%20wish%20to%20map%20to%20a%20database%20table%20column.%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3EThe%20full%20online%20documentation%20for%20this%20ADF%20transformation%20can%20be%20found%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdata-factory%2Fdata-flow-flatten%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EYou%20can%20download%20this%20sample%20pipeline%20demo%20using%20the%20ADF%20Pipeline%20Template%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fkromerm%2Fadfdataflowdocs%2Fblob%2Fmaster%2Fsampledata%2FFlatten%2520Orders.zip%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%20Install%20it%20in%20your%20factory%20by%20going%20to%20New%20%26gt%3B%20Pipeline%20from%20template%20%26gt%3B%20import%20template.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1221106%22%20slang%3D%22en-US%22%3E%3CP%3EThis%20example%20uses%20ADF%20data%20flows%20to%20transform%20complex%20JSON%20structures%20from%20CosmosDB%20to%20SQL%20DB%20with%20Azure%20Data%20Factory%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1221106%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%20Data%20Factory%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%20ETL%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EMapping%20Data%20Flows%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1434933%22%20slang%3D%22en-US%22%3ERe%3A%20Transform%20complex%20JSON%20structures%20from%20CosmosDB%20to%20SQL%20DB%20with%20Azure%20Data%20Factory%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1434933%22%20slang%3D%22en-US%22%3E%3CP%3EThe%20current%20scenarios%20allow%20you%20to%20convert%20Arrays%20or%20Complex%20Types%20(JSON)%20into%20single%20columns%20(as%20mentioned%20in%20this%20post)%20or%20convert%20columns%20into%20JSON.%26nbsp%3B%20However%2C%20is%20there%20a%20way%20to%20convert%20the%20JSON%20back%20to%20the%20string%20representation%20for%20storage%20into%20a%20SQL%20Column%3F%3C%2FP%3E%3CP%3EExample%3A%3C%2FP%3E%3CP%3ESource%3A%3C%2FP%3E%3CPRE%3E%7B%0A%26nbsp%3B%20%26nbsp%3B%20%22id%22%3A%201234%2C%0A%26nbsp%3B%20%26nbsp%3B%20%22data%22%3A%20%7B%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%22name%22%3A%20%22Acme%2C%20Inc.%22%2C%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%22address%22%3A%20%7B%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%22city%22%3A%20%22Seattle%22%2C%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%22state%22%3A%20%22WA%22%2C%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%22zip%22%3A%20%2298195%22%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7D%0A%26nbsp%3B%20%26nbsp%3B%20%7D%2C%0A%26nbsp%3B%20%26nbsp%3B%20%22additionalData%22%3A%20%7B%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%22color%22%3A%20%22red%22%2C%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%22shape%22%3A%20%22square%22%2C%0A%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%22number%22%3A%204%0A%26nbsp%3B%20%26nbsp%3B%20%7D%0A%7D%3C%2FPRE%3E%3CP%3EIn%20this%20case%2C%20I%20don't%20want%20to%20store%20color%2C%20shape%2C%20and%20number%20as%20distinct%20columns%2C%20but%20as%20text%3A%20%7B%20%22color%22%3A%20%22red%22%2C%20%22shape%22%3A%20%22square%22%2C%20%22number%22%3A%204%20%7D.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIs%20this%20possible%20currently%2C%20or%20something%20coming%20in%20the%20future%3F%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1434954%22%20slang%3D%22en-US%22%3ERe%3A%20Transform%20complex%20JSON%20structures%20from%20CosmosDB%20to%20SQL%20DB%20with%20Azure%20Data%20Factory%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1434954%22%20slang%3D%22en-US%22%3E%3CP%3EI%20decided%20to%20move%20this%20to%20a%20%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-data-factory%2Fconvert-arrays-or-complex-types-json-to-string-in-data-flow%2Fm-p%2F1434942%22%20target%3D%22_self%22%3Econversation%3C%2FA%3E%2C%20but%20I%20couldn't%20delete%20my%20comment.%26nbsp%3B%20Sorry%20for%20the%20confusion.%3C%2FP%3E%3C%2FLINGO-BODY%3E
Version history
Last update:
‎Mar 10 2020 03:54 PM
Updated by: