【问题标题】:Unzip folder stored in Azure Databricks FileStore解压缩存储在 Azure Databricks FileStore 中的文件夹
【发布时间】:2020-01-16 09:49:41
【问题描述】:

我已将 *.zip 文件夹上传到我的 Azure Datacricks FileStore:

现在我想解压缩文件夹并将其存储在 FileStore:dbfs:/FileStore/tables/rfc_model。

我知道这应该很容易,但我对在 DB Notebooks 中工作感到困惑......

感谢您的帮助!

更新:

我使用这个公式没有成功:

%sh unzip /FileStore/tables/rfc_model.zip

和

%sh unzip dbfs:/FileStore/tables/rfc_model.zip

更新:

我已将 @Sim 创建的代码复制到我的 Databricks 笔记本中,但出现此错误:

知道如何解决这个问题吗?

【问题讨论】:

  • 你尝试了什么?
  • 在 python 中你也可以使用 Zipfile36。

标签: azure apache-spark databricks


【解决方案1】:

当您使用%sh 时,您正在使用其本地文件系统在驱动程序节点上执行shell 命令。但是,/FileStore/ 不在本地文件系统中,这就是您遇到问题的原因。你可以试试看:

%sh ls /FileStore
# ls: cannot access '/FileStore': No such file or directory

对比

dbutils.fs.ls("/FileStore")
// resX: Seq[com.databricks.backend.daemon.dbutils.FileInfo] = WrappedArray(...)

您必须使用可用于 Databricks 文件系统的解压缩实用程序,或者必须将 zip 从文件存储复制到驱动程序磁盘,解压缩然后复制回/FileStore。

您可以使用file:/... 寻址本地文件系统,例如,

dbutils.fs.cp("/FileStore/file.zip", "file:/tmp/file.zip")

希望这会有所帮助。

旁注 1:Databricks 文件系统管理不是超级直观,尤其是在文件存储方面。例如,理论上,Databricks 文件系统 (DBFS) 在本地挂载为 /dbfs/。但是,/dbfs/FileStore 不处理文件存储,而dbfs:/FileStore 处理。你并不孤单。 :)

旁注 2:如果您需要对许多文件执行此操作,您可以通过创建带有文件路径的 Dataset[String] 而不是 ds.map { name => ... }.collect() 来将工作分配给集群工作人员。 collect 操作将强制执行。在 map 函数的主体中,您必须使用 shell API 而不是 %sh。

旁注 3:不久前,我使用以下 Scala 实用程序在 Databricks 上解压缩。无法验证它是否仍然有效,但它可以给你一些想法。

  def unzipFile(zipPath: String, outPath: String): Unit = {
    val fis = new FileInputStream(zipPath)
    val zis = new ZipInputStream(fis)
    val filePattern = """(.*/)?(.*)""".r
    println("Unzipping...")
    Stream.continually(zis.getNextEntry).takeWhile(_ != null).foreach { file =>
      // @todo need a consistent path handling abstraction
      //       to address DBFS mounting idiosyncracies
      val dirToCreate = outPath.replaceAll("/dbfs", "") + filePattern.findAllMatchIn(file.getName).next().group(1)
      dbutils.fs.mkdirs(dirToCreate)
      val filename = outPath + file.getName
      if (!filename.endsWith("/")) {
        println(s"FILE: ${file.getName} to $filename")
        val fout = new FileOutputStream(filename)
        val buffer = new Array[Byte](1024)
        Stream.continually(zis.read(buffer)).takeWhile(_ != -1).foreach(fout.write(buffer, 0, _))
      }
    }
  }

【讨论】:

  • 一个问题:当您将带有子文件夹的文件夹复制到 DBFS 时,它实际上会在没有我的架构的情况下将所有内容移动到一个文件夹中。您将如何进行这种复制?
  • @cincin21 我不确定您所说的“没有我的架构”是什么意思。文件/文件夹没有架构。 Schema 通常与 Spark 从文件/文件夹中读取数据相关联。
  • 我指的是文件结构,例如文件夹 - 子文件夹 - 文件,当我将带有子文件夹的文件夹拖放到 DBFS 时,它不会存储为原始结构。
  • 我从不依赖 UI 进行关键数据操作,因为 UI 行为可能会在我的控制之外发生变化。我建议您使用代码进行您必须执行的任何数据迁移。 Azure 存储可以在 DBFS 中挂载到/mnt/...。 dbutils.fs.cp(from, to, recurse = true) 将保留文件夹结构......但它会从驱动程序完成所有工作,因此它可能会很慢。在内部,我们有可以使用集群工作者移动/复制目录的实用程序,例如,您可以在数据集中分发目录列表或从/到路径,并从flatMap() 操作调用dbutils.fs.*。
【解决方案2】:

这行得通:

%sh
unzip /dbfs/FileStore/tables/rfc_model.zip

如果需要,需要将结果复制到 dbfs 中的目标位置。

%sh
cp rfc_model /dbfs/FileStore/tables

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    • 2013-10-30
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    相关资源
    最近更新 更多