无法在 pyspark 中覆盖镶木地板配置单元 table

Failing to overwrite parquet hive table in pyspark

使用:火花 1.5.2,蜂巢 1.2 我有一个镶木地板格式的外部配置单元 table。我创建了一个 .py 脚本,它从 my_table 中选择一个数据帧,进行一些转换,然后尝试写回原始 table。

我试过以下方法:

  1. df.write.insertInto('table_name', overwrite='true')

这会引发以下错误:

pyspark.sql.utils.AnalysisException: Cannot insert overwrite into table that is also being read from.

  1. df.write.mode('overwrite').parquet('my_path')
  2. df.write.parquet('my_path', mode='overwrite')
  3. df.write.save('my_path', format='parquet', mode = 'overwrite')

这些似乎都抛出了这个错误:

ERROR Client fs/client/fileclient/cc/client.cc:1802 Thread: 620 Open failed for file /my_path/part-r-00084-9, LookupFid error No such file or directory(2) 2016-04-26 16:47:17,0942 ERROR JniCommon fs/client/fileclient/cc/jni_MapRClient.cc:2488 Thread: 620 getBlockInfo failed, Could not open file /my_path/part-r-00084-9 16/04/26 16:47:17 WARN DAGScheduler: Creating new stage failed due to exception - job: 16

**请注意,如果文件格式是 orc,上面的方法 1 工作正常,但对于 parquet 会抛出该错误。

如有任何建议,我们将不胜感激!

从我目前发现的所有内容来看,读取和写入 parquet 格式文件的解决方案似乎是写入 temporary/staging 目录,删除原始目录,然后重命名临时目录到你原来的目录。 要在 pyspark 中执行此操作,您将需要以下命令:

import os
import shutil
shutil.rmtree('my_tmp_path')
os.rename('my_tmp_path', 'my_path)

为此你需要使用一个临时路径来写入。

问题是 Spark 主动使用实际路径读取数据,当您尝试写入同一个 parquet 文件时,它会生成错误。

Stella 已经给出了 应该做什么,但顺序不对。所以我决定给你一个更好更完整的答案,因为我必须自己解决它:

在下面的代码中,我尝试使用临时文件保存数据框:

def write_dataframe(df, table_name):
   # caches dataframe
   df.cache()

   dirout_tmp = PATH + table_name + "_tmp/"
   dirout = PATH + table_name + "/"
   # writing parquet file to a temporary location
   df.write.parquet(dirout_tmp, mode='overwrite')
   # removing original parquet
   shutil.rmtree(dirout, ignore_errors=True)
   # renaming the temp to the original path
   os.rename(dirout_tmp, dirout)