【发布时间】:2020-01-20 14:42:30
【问题描述】:
这是我面临的问题的一个缩影,我遇到了错误。让我尝试在这里重现它。
我将DataFrame 保存为parquet,但是当我从parquet 文件重新加载DataFrame 并再次将其另存为parquet 时,出现错误。
valuesCol = [('Male','2019-09-06'),('Female','2019-09-06'),('Male','2019-09-07')]
df = spark.createDataFrame(valuesCol,['sex','date'])
# Save as parquet
df.repartition(1).write.format('parquet').mode('overwrite').save('.../temp')
# Load it back
df = spark.read.format('parquet').load('.../temp')
df = df.where(col('sex')=='Male')
# Save it back - This produces ERROR
df.repartition(1).write.format('parquet').mode('overwrite').save('.../temp')
错误信息 -
执行程序 22): java.io.FileNotFoundException: 请求的文件 maprfs:///mapr/.../temp/part-00000-f67d5a62-36f2-4dd2-855a-846f422e623f-c000.snappy.parquet 不存在。基础文件可能已更新。 您可以通过运行“REFRESH”显式地使 Spark 中的缓存无效 SQL 中的 TABLE tableName' 命令或通过重新创建 Dataset/DataFrame 参与。
另一个 SO question 解决了这个问题。建议的解决方案是refresh 表格,如下面的代码,但这没有帮助。问题在于元数据的刷新。不知道怎么刷新。
df.createOrReplaceTempView('table_view')
spark.catalog.refreshTable('table_view')
df.repartition(1).write.format('parquet').mode('overwrite').save('.../temp')
此问题的解决方法: 解决此问题的一种不太优雅的方法是将DataFrame 保存为具有不同名称的parquet 文件,然后删除原始parquet 文件并最后,将此parquet 文件重命名为旧名称。
# Workaround
import os
import shutil
# Load it back
df = spark.read.format('parquet').load('.../temp')
# Save it back as temp1, as opposed to original temp
df.repartition(1).write.format('parquet').mode('overwrite').save('.../temp1')
# Delete the original parquet file
shutil.rmtree('.../temp')
# Renaming the parquet folder.
os.rename('.../temp1','.../temp')
但是,问题是某些 DataFrame 非常大,这可能不是处理它的最佳方法。更不用说重命名是否会导致元数据出现问题,我不确定。
【问题讨论】:
-
您好,我以前看过这个链接,但是由于我不在 HIVE 上,所以我不知道如何在我的情况下使用它。如果您有解决方案,请将其写为答案。这会有很大帮助。谢谢。
标签: python apache-spark metadata parquet