Databricksにローカル環境で開発したpythonコードをimportするノウハウ
このエントリでは、
Databricksで動かすコードを、PyCharmなどのIDEで書きたい場合のノウハウについて示す。
Databricksへのソースコードimport/exportは、以下のエントリで記載したが、
ローカル環境とDatabricks環境で同じコードが動く訳では無いので、
以下の2つの観点で、対応する方法を考える。
- なるべくローカルでも動くように設定する
- 環境に依存するコードを切り替える
Databricks WorkspaceとローカルPC上のソースコードの同期方法
http://takemikami.com/2019/02/01/Databricks-WorkspacePC.html
なるべくローカルでも動くように設定する
Databricks用のコードがなるべくローカル環境でも動くように、以下をインストール・設定する。
- Databricks Utilities
- Apache Spark
Databricks Utilitiesのインストール
Databricks UtilitiesというDatabricks用のパッケージをインストールする。
Databricks Utilities | docs.databricks.com
https://docs.databricks.com/user-guide/dev-tools/dbutils.html
インストール方法は以下の通り。
pip install DBUtils
これをインストールし、以下のようにインポートしておくと、
PyCharmなどで「dbutils.fs.〜」のようなコードに対する警告を抑制出来る。
import DBUtils as dbutils
Apache Sparkのインストール
pysparkをローカル環境で実行出来るようにする方法は、以下エントリの通り。
ApacheSparkをダウンロード&展開し、環境変数「SPARK_HOME」を設定しておけば良い。
IntelliJ IDEAでpyspark用の開発環境を設定する手順
http://takemikami.com/2018/11/27/IntelliJ-IDEApyspark.html
インストールと環境変数を設定した上で、以下のようにインポート・初期化すると、
ローカル環境でDatabricks環境と同じように、pysparkを利用できるようになる。
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('local').getOrCreate()
環境に依存するコードを切り替える
先に記載したDBUtils、SparkSessionのインポートなどローカル環境のみで利用し、
Databricks環境にimportする時には取り除きたいコードが存在する。
この課題に対応するため、
「LOCALONLY」とコメントした行を取り除いてimportするシェルスクリプトを作る。
ついでに、「DBONLY」とコメントした行はコメントインする処理も記載する。
「databricks-cli」のインストール&初期化は以下のエントリの通り実施しておく。
Databricks WorkspaceとローカルPC上のソースコードの同期方法
http://takemikami.com/2019/02/01/Databricks-WorkspacePC.html
以下のシェルスクリプトを作成する。
※WORKSPACE_PATH, TARGET_PATH には対象パスを指定しておく。
#!/bin/sh
# configurations
WORKSPACE_PATH=※import先のPathを記載する※ 例: /Users/user@example.com/sample
TARGET_PATH=※ローカルのソースコード格納先パスを記載する※ 例: sample
SCRIPT_DIR=$(cd $(dirname $0)/.; pwd)
# make working directory
mkdir -p $SCRIPT_DIR/.dbsync_tmp/$TARGET_PATH
# upload source file to databricks
for f in `ls $SCRIPT_DIR/$TARGET_PATH`; do
if [[ $f =~ \.py$ ]]; then
l=PYTHON
cat $SCRIPT_DIR/$TARGET_PATH/$f | grep -v "# *LOCALONLY" | sed "s/^# *\(.*\)# *DBONLY/\1/" > $SCRIPT_DIR/.dbsync_tmp/$TARGET_PATH/$f
elif [[ $f =~ \.scala$ ]]; then
l=SCALA
cat $SCRIPT_DIR/$TARGET_PATH/$f | grep -v "// *LOCALONLY" | sed "s/^\/\/ *\(.*\)\/\/ *DBONLY/\/\1/" > $SCRIPT_DIR/.dbsync_tmp/$TARGET_PATH/$f
elif [[ $f =~ \.r$ ]]; then
l=R
cat $SCRIPT_DIR/$TARGET_PATH/$f > $SCRIPT_DIR/.dbsync_tmp/$TARGET_PATH/$f
else
l=SQL
cat $SCRIPT_DIR/$TARGET_PATH/$f > $SCRIPT_DIR/.dbsync_tmp/$TARGET_PATH/$f
fi
databricks workspace import $SCRIPT_DIR/.dbsync_tmp/$TARGET_PATH/$f $WORKSPACE_PATH/$f -l $l -o
done
# remove working directory
rm -rf $SCRIPT_DIR/.dbsync_tmp
ローカルのソースコード格納先パス配下に、以下のようなコードを置いて、
上記のシェルスクリプトを実行すると、
ローカル用コード除去とコメントインを行った上でDatabricksにインポートされる。
# COMMAND ----------
import DBUtils as dbutils # LOCALONLY
from pyspark.sql import SparkSession # LOCALONLY
spark = SparkSession.builder.appName('local').getOrCreate() # LOCALONLY
# COMMAND ----------
# WORKING_PATH_PARENT = "dbfs:/tmp/sample" # DBONLY
WORKING_PATH_PARENT = "file:///tmp/sample" # LOCALONLY
# COMMAND ----------
# if True: # DBONLY
if __name__ == '__main__': # LOCALONLY
print("sample")
具体的に上記のコードに対して、
ローカル用のコード除去とコメントインされたものは、以下のコードになる。
# COMMAND ----------
# COMMAND ----------
WORKING_PATH_PARENT = "dbfs:/tmp/sample"
# COMMAND ----------
if True:
print("sample")
以上。