Распакуйте папку, хранящуюся в Azure Databricks FileStore - PullRequest
3 голосов
/ 16 января 2020

Я загрузил папку * .zip в мой Azure Datacricks FileStore:

enter image description here

Теперь я хотел бы распаковать папку и сохранить его в FileStore: dbfs: /FileStore/tables/rfc_model.

Я знаю, что это должно быть легко, но я запутался, работая в тетрадях БД ...

Спасибо за помощь!

ОБНОВЛЕНИЕ:

Я использовал эти формулы безуспешно:

%sh unzip /FileStore/tables/rfc_model.zip

и

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

ОБНОВЛЕНИЕ:

Я скопировал код, созданный @Sim, в мою записную книжку Databricks, но появляется эта ошибка:

enter image description here

Есть идеи как это исправить?

Ответы [ 2 ]

3 голосов
/ 21 января 2020

Когда вы используете %sh, вы выполняете команды оболочки на узле драйвера, используя его локальную файловую систему. Однако /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(). Действие по сбору приведет к выполнению. В теле функции map вы должны будете использовать 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, _))
      }
    }
  }
1 голос
/ 07 мая 2020

Это работает:

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

Результаты должны быть скопированы в пункт назначения в dbfs, если необходимо.

%sh
cp rfc_model /dbfs/FileStore/tables
...