如何使用PySpark在原位置覆盖Parquet文件
问题描述
在Azure Synapse笔记本中使用PySpark处理Parquet文件时,执行列重命名等转换后将DataFrame保存回原路径覆盖文件,发现保存后生成了Test.parquet目录,目录内包含_SUCCESS文件和随机命名的数据文件,而非直接覆盖原Parquet文件。使用的代码如下:
%%pyspark df = spark.read.load('path/to/Test.parquet', format='parquet') display(df.limit(10)) column_mapping = { "FullName": "Full Name", } for old_col, new_col in column_mapping.items(): df = df.withColumnRenamed(old_col, new_col) display(df.limit(10)) df.write.parquet('path/to/Test.parquet', mode='overwrite')
解决方案
Spark默认以分布式方式写入Parquet文件,因此会生成包含多个数据文件、_SUCCESS标记的目录,这是其分布式计算特性导致的。要实现直接覆盖原Parquet文件且不生成额外目录,可通过临时目录中转的方式处理,具体步骤如下:
方法1:临时目录中转(通用方案,适合大数据量)
先将处理后的DataFrame写入临时目录,再将临时目录中的数据文件移动到原路径,最后清理临时文件:
%%pyspark # 读取原Parquet文件 df = spark.read.parquet('path/to/Test.parquet') # 执行列重命名转换 column_mapping = {"FullName": "Full Name"} for old_col, new_col in column_mapping.items(): df = df.withColumnRenamed(old_col, new_col) # 定义临时存储路径 temp_path = 'path/to/temp_Test_parquet' # 将处理后的数据写入临时目录(覆盖已有临时文件) df.write.mode('overwrite').parquet(temp_path) # 删除原路径下的文件/目录 dbutils.fs.rm('path/to/Test.parquet', recurse=True) # 将临时目录中的数据文件移动到原路径(跳过_SUCCESS文件) for file in dbutils.fs.ls(temp_path): if not file.name.endswith('_SUCCESS'): dbutils.fs.mv(file.path, 'path/to/Test.parquet') # 删除临时目录 dbutils.fs.rm(temp_path, recurse=True)
方法2:生成单个Parquet文件(适合小数据量)
如果业务要求必须生成单个Parquet文件,可在写入前使用coalesce(1)将数据合并到一个分区,再通过临时目录中转:
%%pyspark # 读取原Parquet文件 df = spark.read.parquet('path/to/Test.parquet') # 执行列重命名转换 column_mapping = {"FullName": "Full Name"} for old_col, new_col in column_mapping.items(): df = df.withColumnRenamed(old_col, new_col) # 定义临时存储路径 temp_path = 'path/to/temp_Test_parquet' # 合并分区为1,写入临时目录 df.coalesce(1).write.mode('overwrite').parquet(temp_path) # 删除原路径下的文件/目录 dbutils.fs.rm('path/to/Test.parquet', recurse=True) # 移动临时目录中的单个数据文件到原路径 for file in dbutils.fs.ls(temp_path): if file.name.endswith('.parquet'): dbutils.fs.mv(file.path, 'path/to/Test.parquet') # 删除临时目录 dbutils.fs.rm(temp_path, recurse=True)
注意事项
coalesce(1)会将所有数据集中到单个Executor节点,大数据量场景下会严重影响性能,仅适合小数据量使用。- 若不需要保留
_SUCCESS文件,在移动时直接跳过即可;如果业务需要该标记,也可选择将其移动到原路径目录下(但这样会生成目录,不符合需求)。
内容的提问来源于stack exchange,提问作者Moody_girl
相关产品推荐
相关产品推荐

