PySpark如何以当前日期时间为名保存CSV且不生成嵌套文件夹
问题根因
原代码存在4个核心问题,导致达不到预期效果:
- Spark的
DataFrameWriter.csv()方法的入参是输出目录路径,而非单文件路径。这是Spark分布式写入的原生设计:无论设置coalesce(1)还是repartition(1),Spark都会在传入的路径下创建专属目录,目录内放置分片数据文件、任务成功标记文件_SUCCESS、校验文件等,不会直接生成指定名称的单个CSV文件。 - 路径字符串未做变量插值:代码中写的
"{date}.csv"是普通字符串,没有将date变量的实际值替换进去,所以会生成字面量名为{date}.csv的文件夹。 - 时间格式配置错误:使用的
strftime("%Y_%m_%d-%I:%M:%S_%p")生成的是「年_月_日-时间」格式,和要求的「日-月-年 时:分:秒 AM/PM」格式不匹配。 - 写入模式配置无效:
mode是DataFrameWriter的独立方法,放在option()中传入不会被识别,无法生效。
修正方案
方案全程使用PySpark内置能力实现,不依赖原生Python文件系统操作,可直接在Azure Synapse Notebook环境运行,通过Spark自带的Hadoop FileSystem API操作ABFSS路径,复用Synapse内置的存储账号权限配置:
- 生成符合命名规则的时间戳
- 将DataFrame合并为单分片后写入临时目录
- 遍历临时目录找到实际存储数据的CSV分片文件,通过Hadoop API将其重命名为目标文件名,移动到数据湖根路径
- 清理临时写入目录,最终在目标路径下直接生成指定名称的CSV文件,无嵌套文件夹
可直接运行的参考代码如下:
from datetime import datetime from pyspark.sql import SparkSession # 生成符合要求的时间戳:格式为 日-月-年 时:分:秒 AM/PM current_ts = datetime.now().strftime("%d-%m-%Y %I:%M:%S %p") target_file_name = f"{current_ts}.csv" # 配置路径参数 base_path = "abfss://livetwt@strcxxxxxx.dfs.core.windows.net/" # 临时目录名替换特殊字符避免路径解析错误,执行完成后会自动删除 temp_dir = f"{base_path}/temp_csv_output_{current_ts.replace(' ','_').replace(':','_')}" target_file_path = f"{base_path}/{target_file_name}" # 合并为1个分片写入临时目录 df.coalesce(1).write.mode("overwrite").option("header", "true").option("sep", ",").csv(temp_dir) # 调用Spark内置Hadoop API操作数据湖文件 sc = SparkSession.builder.getOrCreate().sparkContext hadoop_conf = sc._jsc.hadoopConfiguration() fs = sc._jvm.org.apache.hadoop.fs.FileSystem.get(sc._jvm.java.net.URI(base_path), hadoop_conf) temp_dir_path = sc._jvm.org.apache.hadoop.fs.Path(temp_dir) target_path = sc._jvm.org.apache.hadoop.fs.Path(target_file_path) # 过滤临时标记文件,找到实际CSV数据文件并重命名为目标名称 for file_status in fs.listStatus(temp_dir_path): file_path = file_status.getPath() file_name = file_path.getName() if not file_name.startswith("_") and not file_name.startswith(".") and file_name.endswith(".csv"): fs.rename(file_path, target_path) break # 递归删除临时目录 fs.delete(temp_dir_path, True)
执行完成后,可直接在数据湖容器根路径找到命名格式为
29-06-2022 15:30:25 PM.csv的目标文件,无额外嵌套目录。
内容的提问来源于stack exchange,提问作者sthambi
相关产品推荐
相关产品推荐

