Azure Data Factory v2:如何按行生成单个JSON文件
嘿,刚好我之前处理过类似的需求,ADF复制活动本身确实没办法直接把SQL的每一行导出成单独的Blob文件,不过我们可以通过两种常用方案来实现,我给你详细拆解下:
方案一:ForEach活动 + 复制活动(适合小数据量/需精细控制场景)
这个方案的核心思路是先获取SQL表的所有行标识,再循环遍历每一行,单独复制到Blob文件中:
- 第一步:添加Lookup活动,配置Azure SQL数据集作为源,写一个查询获取所有行的唯一标识(比如主键列),比如
SELECT id FROM 你的表名。这个活动会把所有主键值返回为一个数组。 - 第二步:添加ForEach活动,把迭代项设置为
@activity('Lookup活动名称').output.value,如果你的SQL表数据量不大,可以保持默认并发;如果数据量稍大,建议开启Sequential(顺序执行)避免资源冲突。 - 第三步:在ForEach内部添加复制活动:
- 输入数据集:配置Azure SQL数据集,在数据集的查询里写动态SQL,只取当前循环的那一行:
SELECT * FROM 你的表名 WHERE id = '@item().id'(把id换成你的主键列名)。 - 输出数据集:配置Azure Blob数据集,设置文件路径和名称为动态内容,比如
@concat('output-files/', item().id, '.json'),这样每个文件对应唯一的行。 - 如果输出是JSON格式,记得把Blob数据集的
filePattern设为setOfObjects,这样输出的文件就是单个JSON对象(刚好对应一行SQL数据),而不是数组包裹的格式。
- 输入数据集:配置Azure SQL数据集,在数据集的查询里写动态SQL,只取当前循环的那一行:
方案二:映射数据流(适合大数据量/高性能场景)
如果你的SQL表数据量很大,ForEach循环的效率会很低,这时候用映射数据流是更好的选择:
- 第一步:创建映射数据流,添加Azure SQL作为源,读取全表数据。
- 第二步:添加Blob作为Sink(输出),配置好存储账户和容器:
- 在Sink的设置标签页,找到文件名选项,选择「列中的数据」,然后指定你的唯一标识列(比如主键id)作为文件名的一部分,或者用
@toString(UUID())生成随机唯一文件名,确保每个文件对应一行。 - 在Sink的格式设置里,把文件模式设为
setOfObjects,这样每行数据会被输出为独立的JSON对象,配合按行拆分的文件名,每个Blob文件就只包含一行SQL数据。 - 如果需要输出CSV格式,直接把格式改成CSV,不需要额外设置文件模式,只要确保文件名是唯一的即可。
- 在Sink的设置标签页,找到文件名选项,选择「列中的数据」,然后指定你的唯一标识列(比如主键id)作为文件名的一部分,或者用
注意事项
- 用ForEach方案时,注意控制并发数,ADF默认并发是20,根据你的SQL数据库和Blob存储的性能调整,避免触发限流。
- 如果你的SQL表没有唯一主键,可以用
ROW_NUMBER()函数生成临时唯一标识,比如在Lookup活动的查询里写SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS row_id FROM 你的表名,然后用row_id作为循环标识。
内容的提问来源于stack exchange,提问作者Simon Zeinstra
相关产品推荐
相关产品推荐

