LoginSignup
2
1

More than 1 year has passed since last update.

Databricksファイルシステム(DBFS)上のファイルを圧縮してダウンロードする

Last updated at Posted at 2022-08-09

なにかしらの処理の結果、生成される複数のファイルを簡単にダウンロードできるように圧縮を行い、zipファイルへのリンクを表示するサンプルです。

サンプルノートブックはこちらです。

参考資料

ファイルの準備

ダミーデータを準備します。以下のパスは適宜変更してください。

Python
# 処理の結果が格納されるパスです
output_file_path = "/tmp/takaaki.yayoi@databricks.com/processed"

# ブラウザからダウンロードできるようにFileStore配下のパスとします
download_file_path = "/FileStore/shared_upload/takaaki.yayoi@databricks.com/viz_results"

現在時刻を用いてフォルダを作成します。

Python
# datetimeモジュールを使用
import datetime

t_delta = datetime.timedelta(hours=9)
JST = datetime.timezone(t_delta, 'JST')
now = datetime.datetime.now(JST)
#print(repr(now))

# YYYYMMDDhhmmss形式に書式化
directory_name = now.strftime('%Y%m%d-%H%M%S')
#print(d)

target_path = f"{output_file_path}/{directory_name}"
print("target path:", target_path)

# 日付の入ったディレクトリを作成
dbutils.fs.mkdirs(target_path)

Screen Shot 2022-08-09 at 15.31.49.png

ワインデータセットをコピーします。

Python
dbutils.fs.cp("dbfs:/databricks-datasets/wine-quality/winequality-red.csv", target_path)
dbutils.fs.cp("dbfs:/databricks-datasets/wine-quality/winequality-white.csv", target_path)
dbutils.fs.cp("dbfs:/databricks-datasets/wine-quality/README.md", target_path)
Python
# ファイルが格納されていることを確認
display(dbutils.fs.ls(target_path))

Screen Shot 2022-08-09 at 15.32.14.png

ファイル圧縮

DBFSの実態はオブジェクトストレージなので、ランダムアクセスが必要となるファイル圧縮をその場で行うことができません。このため、クラスターのローカルストレージに一旦コピーして圧縮を行う必要があります。

dbutils.fsでパスを指定する際にローカルストレージを参照するには、パスの先頭にfile:をつけます。正直ここは分かりにくいところだと思います。

こちらで触れているように、使っているAPIによってデフォルトでDBFS(分散ファイルシステム)にアクセスするのか、ローカルファイルシステムにアクセスするのかが異なります。このデフォルトの挙動を変えるためにfile:/dbfsを使います。

  • Spark API、%fsdbutils.fsなどは、デフォルトのアクセス先はDBFSになります。
  • 一方、pandasなどのシングルマシン向けPythonライブラリ(ローカルファイルシステムAPI)、%shなどは、デフォルトのアクセス先はローカルファイルシステムになります。

以下で使用しているshutilではファイルの圧縮を行いますが、上述の通り、DBFS上に直接圧縮ファイルを作成することができません。このため、DBFSからローカルファイルシステムにファイルをコピーしています。この際にdbutils.fs.cpを使っています。これのデフォルトのアクセス先はDBFSとなるので、ここでローカルファイルシステムを参照するには、パスの先頭にfile:を追加します。

なお、ローカルファイルシステムAPIでDBFSを参照するには、パスの先頭に/dbfsを追加します。以下の図にまとめていますが、これでも正直分かりにくいと思います。まずは以下の2点を覚えていただくといいのではと思います。

パスのプレフィックス

  • pandasでローカルファイルシステムにアクセスするにはパスはそのまま、DBFSにアクセスするにはパスの先頭に/dbfsを追加します。
  • Spark APIや%fsでDBFSにアクセスするにはパスはそのまま、ローカルファイルシステムにアクセスするにはパスの先頭にfile:を追加します。

参考資料

Python
# DBFSからローカルストレージにコピー
dbutils.fs.cp(target_path, f"file:/tmp/{directory_name}", True)
Python
# ローカルストレージを参照
display(dbutils.fs.ls(f"file:/tmp/{directory_name}"))

Screen Shot 2022-08-09 at 15.32.53.png

shutilを使って圧縮を行います。

Python
# ディレクトリを圧縮
import shutil
shutil.make_archive(f"/tmp/{directory_name}", format='zip', root_dir=f'/tmp/{directory_name}')

Screen Shot 2022-08-09 at 15.33.14.png

ブラウザからダウンロードできるように、DBFSの/FileStoreにファイルをコピーします。

Python
dbutils.fs.cp(f"file:/tmp/{directory_name}.zip", f"{download_file_path}/{directory_name}.zip")
Python
display(dbutils.fs.ls(download_file_path))

Screen Shot 2022-08-09 at 15.34.23.png

ダウンロードリンクの生成

DBFSのFileStore配下のファイルには、ブラウザから/filesのURLを指定することでアクセスすることができます。

Python
import re

# FileStoreをfilesに置き換えます
download_url_path = re.sub("FileStore", "files", download_file_path)
print(download_url_path)

displayHTML関数を使ってリンクをノートブック上にレンダリングします。

Python
displayHTML (f"""
<a href='{download_url_path}/{directory_name}.zip'>{directory_name}.zip</a>
""")

Screen Shot 2022-08-09 at 15.35.53.png

このリンクをクリックするとzipファイルがローカルにダウンロードされます。これを解凍すると、上で圧縮した3つのファイルを手に入れることができます。
Screen Shot 2022-08-09 at 15.36.57.png

Databricks 無料トライアル

Databricks 無料トライアル

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1