如何在Azure Synapse中用PySpark将ADLS的JSON转存为指定名称的CSV
解决Azure Synapse中JSON转CSV指定输出文件名的问题
在Azure Synapse中,Spark默认按分区生成part-xxx.csv文件和_success标记文件,要输出指定名称的单一CSV文件,可通过以下两种常用方法实现:
方法1:Spark合并分区后重命名(适合小数据集)
通过coalesce(1)将数据合并到单个分区,写入临时目录后再将生成的part文件重命名为指定名称,同时清理临时文件。
# 读取ADLS中的JSON文件 df = spark.read.json("abfss://<容器名>@<存储账户名>.dfs.core.windows.net/path/to/sfmc.json") # 定义临时输出路径与最终目标路径 temp_output_path = "abfss://<容器名>@<存储账户名>.dfs.core.windows.net/path/to/temp_dir/" target_csv_path = "abfss://<容器名>@<存储账户名>.dfs.core.windows.net/path/to/sfmc.csv" # 合并分区后写入临时目录(需保留表头则添加header=True) df.coalesce(1).write.mode("overwrite").option("header", "true").csv(temp_output_path) # 定位临时目录下的CSV part文件 part_files = dbutils.fs.ls(temp_output_path) target_part_file = [file.path for file in part_files if file.name.startswith("part-") and file.name.endswith(".csv")][0] # 重命名part文件到目标路径 dbutils.fs.mv(target_part_file, target_csv_path) # 删除临时目录及附属文件 dbutils.fs.rm(temp_output_path, recurse=True)
注意:coalesce(1)会将所有数据集中到一个分区,大数据集可能引发内存溢出,此类场景建议使用方法2。
方法2:Serverless SQL池导出(适合大数据集)
利用Serverless SQL池读取JSON并直接导出为指定名称的CSV,避免Spark合并分区的性能瓶颈。
-- 创建指向ADLS的外部数据源 CREATE EXTERNAL DATA SOURCE ADLS_DataSource WITH ( LOCATION = 'abfss://<容器名>@<存储账户名>.dfs.core.windows.net/', TYPE = HADOOP ); -- 创建JSON格式的外部文件格式 CREATE EXTERNAL FILE FORMAT JSON_Format WITH ( FORMAT_TYPE = JSON -- 若JSON为GZIP压缩,添加此行:DATA_COMPRESSION = 'org.apache.hadoop.io.compress.GzipCodec' ); -- 创建外部表映射JSON结构 CREATE EXTERNAL TABLE dbo.SFMC_JSON ( -- 需与JSON字段一一对应,示例: ID INT, UserName VARCHAR(100), Email VARCHAR(100) ) WITH ( LOCATION = 'path/to/sfmc.json', DATA_SOURCE = ADLS_DataSource, FILE_FORMAT = JSON_Format ); -- 导出数据到指定CSV文件 COPY INTO 'path/to/sfmc.csv' FROM (SELECT * FROM dbo.SFMC_JSON) WITH ( DATA_SOURCE = ADLS_DataSource, FILE_TYPE = 'CSV', FIELDTERMINATOR = ',', ROWTERMINATOR = '0x0A', HEADER_ROW = TRUE, OVERWRITE = TRUE );
注意:需确保Serverless SQL池拥有ADLS的读写权限(如通过工作区MSI分配存储Blob数据贡献者角色),且外部表列结构需与JSON字段匹配。
补充说明
_success文件:Spark写入时默认生成,方法1中删除临时目录会连带清除该文件;若需保留_success,可仅移动part文件至目标路径,保留临时目录。- 权限要求:执行脚本的身份需具备ADLS容器的读写权限,避免出现访问被拒的错误。
内容的提问来源于stack exchange,提问作者Athiya
相关产品推荐
相关产品推荐

