Glueジョブの引数にJSONを渡す方法
データアナリティクス事業本部の森脇です。
Sparkを簡単に動かしたい場合にAWS Glueジョブは非常に便利です。
AWS Glueジョブは実行時に引数を渡すことができますが、JSONのような構造化データをそのまま渡すことができるのか、気になったので調べてみました。
AWSの公式ドキュメントから調べてみる
https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-programming-python-calling.htmlに記載がありました。
ネストされた JSON 文字列である引数を渡す場合、AWS Glue ETL ジョブに渡されるときにパラメータ値を保持するには、ジョブの実行を開始する前にパラメータ文字列をエンコードし、パラメータ文字列をデコードしてからジョブ・スクリプトを参照する必要があります。
JSONを渡したい場合、エンコードする必要があるようです。
上記ドキュメントにサンプルがのっていたので、それを試してみます。
JSON文字列をそのまま渡すケース
ネストした辞書をJSON文字列に変換し、そのままジョブの引数に渡してみます。
import json import boto3 glue = boto3.client('glue') sample = {"a": {"b": {"c": [{"d": {"e": 42}}]}}} sample_json = json.dumps(sample) resp = glue.start_job_run( JobName="SampleJob", Arguments={ "--SAMPLE": sample_json, }, ) print(resp)
ここで実行するとエラーがでるはず。。。なんですが、上手くいってしまいました。
$ python3 run-job-blog.py {'JobRunId': 'jr_f3351f583e2e3b986061da425b25f7dc8549dfa9bc3c95262da029dfd8028d92', 'ResponseMetadata': {'RequestId': '5c2a96c7-74a3-458f-854f-1639e8c9a955', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Fri, 28 May 2021 02:13:01 GMT', 'content-type': 'application/x-amz-json-1.1', 'content-length': '82', 'connection': 'keep-alive', 'x-amzn-requestid': '5c2a96c7-74a3-458f-854f-1639e8c9a955'}, 'RetryAttempts': 0}}
Glueジョブ側のログでも、正常に認識されていました。
エラーになってほしかったんですが、場合によってはエンコードしなくても引数に指定できるようです。
base64にエンコードして渡すケース
推奨の方法である、base64エンコードして渡します。
import json import boto3 import base64 glue = boto3.client('glue') sample = {"a": {"b": {"c": [{"d": {"e": 42}}]}}} sample_json = json.dumps(sample) encoded = base64.b64encode(sample_json.encode("ascii")) encoded_str = encoded.decode("ascii") resp = glue.start_job_run( JobName="ProtoCreateHudiTable", Arguments={ "--SAMPLE": encoded_str, }, ) print(resp)
Glueジョブ側のコードでデコードする必要がありますが、こちらの方が安全に渡せますね。
まとめ
GlueジョブでJSONを渡す方法を調べてみました。
JSON文字列を直接指定して問題ないケースはあるのものの、base64等でデコードするのが良さそうでした。