You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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内置的存储账号权限配置:

  1. 生成符合命名规则的时间戳
  2. 将DataFrame合并为单分片后写入临时目录
  3. 遍历临时目录找到实际存储数据的CSV分片文件,通过Hadoop API将其重命名为目标文件名,移动到数据湖根路径
  4. 清理临时写入目录,最终在目标路径下直接生成指定名称的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:57:14