Azure Synapse中PySpark替换Parquet文件时遇FileNotFoundException
Azure Synapse PySpark 替换Parquet文件报错解决办法
问题根源
Spark DataFrame采用懒执行机制:你定义的df_variance只是保存了数据处理的逻辑,并没有实际读取原Parquet文件的数据到内存或磁盘。当你手动删除原文件后,执行count()、写入等触发计算的操作时,Spark才会尝试去读取原路径的文件,此时文件已不存在,自然抛出FileNotFoundException。
解决办法
1. 提前物化DataFrame再删除原文件
在删除原文件前,强制Spark完成数据读取并将结果缓存,确保后续操作不再依赖原文件路径:
# 读取原Parquet文件 df = spark.read.parquet(full_file_path) # 创建临时视图并生成过滤后的DataFrame df.createOrReplaceTempView("temp_table") df_variance = spark.sql("""SELECT * FROM temp_table WHERE ....""") # 缓存DataFrame到内存(大数据量可改用磁盘存储) df_variance.cache() # 执行count()触发数据加载,完成物化 df_variance.count() # 此时可以安全删除原文件 mssparkutils.fs.rm(full_file_path, True) # 执行后续写入或统计操作 df_variance.write.parquet(full_file_path, mode="overwrite")
如果数据量过大,内存缓存压力高,可替换cache()为persist(StorageLevel.DISK_ONLY),将数据持久化到磁盘。
2. 临时路径中转写入
先将新DataFrame写入临时路径,删除原文件后再移动临时文件到目标路径,彻底避免原文件依赖:
# 定义临时路径 temp_path = f"{full_file_path}_temp" # 读取并生成目标DataFrame df = spark.read.parquet(full_file_path) df.createOrReplaceTempView("temp_table") df_variance = spark.sql("""SELECT * FROM temp_table WHERE ....""") # 将结果写入临时路径 df_variance.write.parquet(temp_path, mode="overwrite") # 删除原文件 mssparkutils.fs.rm(full_file_path, True) # 将临时路径的文件移动到原目标路径 mssparkutils.fs.mv(temp_path, full_file_path, True)
这种方法适合超大数据量场景,无需占用计算节点内存。
3. 直接使用Spark的Overwrite模式(推荐)
Spark的Parquet写入原生支持overwrite模式,无需手动删除原文件,Spark会自动处理覆盖逻辑:
df = spark.read.parquet(full_file_path) df.createOrReplaceTempView("temp_table") df_variance = spark.sql("""SELECT * FROM temp_table WHERE ....""") # 直接覆盖原路径文件,无需手动删除 df_variance.write.parquet(full_file_path, mode="overwrite")
注意:如果原路径是分区表,
overwrite默认会覆盖整个表;若需仅覆盖特定分区,需在写入时指定partitionBy参数并过滤对应分区数据。
内容的提问来源于stack exchange,提问作者datawrangler
相关产品推荐
相关产品推荐

