使用 dbutils 在 Databricks 中上传后从目录中删除文件

Posted

技术标签:

【中文标题】使用 dbutils 在 Databricks 中上传后从目录中删除文件【英文标题】:Remove Files from Directory after uploading in Databricks using dbutils 【发布时间】:2019-01-08 12:27:05 【问题描述】:

*** 的一个非常聪明的人在这里帮助我将文件从 Databricks 复制到一个目录: copyfiles

如链接所示,一旦复制文件,我将使用相同的原则删除文件:

for i in range (0, len(files)):
  file = files[i].name
  if now in file:  
    dbutils.fs.rm(files[i].path,'/mnt/adls2/demo/target/' + file)
    print ('copied     ' + file)
  else:
    print ('not copied ' + file)

但是,我收到了错误:

TypeError: '/mnt/adls2/demo/target/' 的类型错误 - 应为 bool 类。

谁能告诉我如何解决这个问题。我认为在最初使用命令dbutils.fs.rm 复制文件后删除文件会很简单

【问题讨论】:

好的,上面的例子没有反映我们在生产中的脚本:for i in range (0, len(files)): file = files[i].name if now in file: dbutils.fs.rm(files[i].path,'adl://xxxxxxxxxxxx.azuredatalakestore.net/Folder Structure/RAW/1stParty/LCMS/DE/stageone/') print ('removed ' + file) else: print ('not removed ' + file) 问题是因为我错过了左括号。所以,问题不是如上所述预期错误的类型类 bool,问题是print ('removed ' + file) 处的无效语法错误。我希望这有助于解决。 【参考方案1】:

如果要删除以下路径中的所有文件:'/mnt/adls2/demo/target/',有一个简单的命令:

dbutils.fs.rm('/mnt/adls2/demo/target/', True)

无论如何,如果你想使用你的代码,看看dbutils doc:

rm(dir: String, recurse: boolean = false): boolean -> 删除文件或目录

函数的第二个参数应该是布尔值,但是你的代码有带路径的字符串:

dbutils.fs.rm(files[i].path, '/mnt/adls2/demo/target/' + file)

所以你的新代码可以如下:

for i in range (0, len(files)):
    file = files[i].name
        if now in file:  
            dbutils.fs.rm(files[i].path + file, True)
            print ('copied     ' + file)
        else:
            print ('not copied ' + file)

【讨论】:

哇@Fabio,我会在早上测试这个。如果这行得通,我将无法理解 Databricks 专家(我与他们签订了支持合同)是如何解决这个问题的。提前致谢。我会让你知道我是如何处理它的。干杯 您建议的以下命令删除文件夹以及文件dbutils.fs.rm('/mnt/adls2/demo/target/', True) 我只需要删除文件 我们生产中的实际命令是dbutils.fs.rm('adl://devszendsadlsrdpacqncd.azuredatalakestore.net/Folder Structure/RAW/1stParty/LCMS/DE/stageone', True) 你好@Carltonp,抱歉我迟到了。所以我知道你不能删除文件夹。我有一个建议,您可以使用dbutils.fs.rm('/mnt/adls2/demo/target/', True),然后您可以再次创建一个文件夹dbutils.fs.mkdirs('/mnt/adls2/demo/target/', True) ...如果它不适合您,您可以列出所有文件并像之前尝试过的那样逐个删除 'use dbutils.fs.rm('/mnt/adls2/demo/target/', True) 所以在那之后你可以再次创建一个文件夹'这正是我所做的。非常感谢你。另外,只是为了让您知道您的两个建议都有效。我希望你不介意,但我已经与 Databricks 分享了你的解决方案。谢谢大佬【参考方案2】:

如果您有大量文件,以这种方式删除它们可能需要很长时间。您可以利用 spark 并行性来并行删除文件。我提供的答案在 scala 中,但可以更改为 python。

您可以使用以下功能检查目录是否存在:

import java.io._
def CheckPathExists(path:String): Boolean = 

  try
  
    dbutils.fs.ls(path)
    return true
  
  catch
  
    case ioe:java.io.FileNotFoundException => return false
  

您可以定义一个用于删除文件的函数。您正在一个对象内创建此函数,并从 Serializable 类扩展该对象,如下所示:

object Helper extends Serializable

def delete(directory: String): Unit = 
    dbutils.fs.ls(directory).map(_.path).toDF.foreach  filePath =>
      println(s"deleting file: $filePath")
      dbutils.fs.rm(filePath(0).toString, true)
    
  

现在您可以先检查路径是否存在,如果返回true,则可以调用删除函数在多个任务中删除文件夹中的文件。

val directoryPath = "<location"
val directoryExists = CheckPathExists(directoryPath)
if(directoryExists)

Helper.delete(directoryPath)

【讨论】:

【参考方案3】:

为了从 dbfs 中删除文件,您可以在任何笔记本上写这个

%fs rm -r dbfs:/user/sample_data.parquet

【讨论】:

以上是关于使用 dbutils 在 Databricks 中上传后从目录中删除文件的主要内容,如果未能解决你的问题,请参考以下文章

如何以特定顺序使用 Databricks dbutils 复制文件

从 Databricks 中的 dbutils.fs.ls 输出创建数据框

databricks python dbutils无法将文件从一个目录移动到另一个目录

Azure Databricks Notebook 在包中时无法找到“dbutils”

带有 python 的 Azure Databricks dbfs

无法在 Databricks 中使用 SecretKey