はじめに
データの加工処理によく使用するAWS Glueは、Jupyter Notebookを用いてインタラクティブに開発できる環境を提供しています。
これによってGlueの開発体験が劇的に向上しました。
そこで課題となるのが、”インタラクティブセッションでの開発時と、JOB実行時で、同じスクリプトにしたい”という点です。
開発都度、”インタラクティブセッション用のスクリプト部分をコメントアウトして、JOB実行時用のスクリプトをアンコメントする”ということをやるのはミスを招きかねず、何か問題が発生した際にその部分の影響を考慮に入れなければならなくなります。
今回はパラメータを与える方法について、これらの課題を解決する私なりの案を記事にしてみました。
参考
結論
まずインタラクティブセッションで使用するパラメータを宣言します。
# インタラクティブセッションで使うパラメータの値
dicParams = {
'hogehoge':'インタラクティブほげほげ',
'mogemoge':'インタラクティブもげもげ'
}
次に、JOB実行時の際は上記で宣言したパラメータのkeyで引数を取得・上書きする処理を記述します。
# JOBでの実行時は'--JOB_ID'が入ってくるようなので、それを判断基準とする
if '--JOB_ID' in sys.argv:
args = getResolvedOptions( sys.argv,list( dicParams.keys() ) )
for eachParamKey in dicParams:
dicParams[eachParamKey] = args[eachParamKey]
試したこと
以下、調査時に行ったことです。
パラメータなし時の動き
まず、パラメータを取り出す際に用いられるsys.argvに何が入ってくるのかを見てみました。
print(sys.argv)
['/tmp/7435407421286361']
JOB実行の際は、Runsタブにある実行したJOBのところから、CloudWatchへのリンクがあります。
['/tmp/20221107-sample.py', 'true', 'library-set', 'analytics', '--JOB_ID', '<ID文字列>', '--encryption-type', 'sse-s3', '--JOB_RUN_ID', '<ID文字列>', '--JOB_NAME', '20221107-sample', '--TempDir', '<出力先S3パス>']
パラメータあり時の動き
パラメータを入れて実行するには、Run with parameters
で指定します。
たたまれているJob parametersを開いて、KeyとValueを記載します。
インタラクティブセッションにこの設定は影響がなく、sys.argvの結果に変わりありません。
一方JOB実行では引数が入ってきます。
['/tmp/20221107-sample.py', 'true', 'library-set', 'analytics', '--hogehoge', 'ほげほげ', '--JOB_ID', '<ID文字列>', '--encryption-type', 'sse-s3', '--JOB_RUN_ID', '<ID文字列>', '--JOB_NAME', '20221107-sample', '--TempDir', '<出力先S3パス>']
パラメータを取り出す
取り出すためには以下の様にします。
args = getResolvedOptions(sys.argv,['hogehoge'])
print(args['hogehoge'])
パラメータを与えてJOB実行すると、ログから取得できることが確認できます。
ほげほげ
ですがインタラクティブセッションではエラーになります。
GlueArgumentError: the following arguments are required: --hogehoge
起動方法で分岐
これらを考慮して、「インタラクティブセッションの時はパラメータをセルで定義」し、「JOB実行の時は与えられたパラメータを使用する」という風にしました。
以下は最初に書いた内容にprintを入れただけになります。
# インタラクティブセッションで使うパラメータの値
dicParams = {
'hogehoge':'インタラクティブほげほげ',
'mogemoge':'インタラクティブもげもげ'
}
# JOBでの実行時は'--JOB_ID'が入ってくるようなので、それを判断基準とする
if '--JOB_ID' in sys.argv:
args = getResolvedOptions( sys.argv,list( dicParams.keys() ) )
for eachParamKey in dicParams:
dicParams[eachParamKey] = args[eachParamKey]
print(dicParams)
それぞれの実行状態での結果は以下です。
{'hogehoge': 'インタラクティブほげほげ', 'mogemoge': 'インタラクティブもげもげ'}
{'hogehoge': 'JOBほげほげ', 'mogemoge': 'JOBもげもげ'}
想定通り、インタラクティブセッション時もJOB実行時も、スクリプトを修正することなく動かすことができました。
Step Functionsからも起動させてみます。パラメータは以下の様に与えました。
(ロールは自動で作成して)実行すると、ログには以下の様に出てきました。
{'hogehoge': 'StepFunctionsほげほげ', 'mogemoge': 'StepFunctionsもげもげ'}
おわりに
Jupyter Notebookはインタラクティブにスクリプトを記述できるので、複雑な処理を開発する際には大変強力です。
せっかくの開発体験を損なわないよう考えた案を紹介しました。
他にいい案や工夫がある方は是非教えていただけると助かります。