AWS Glue Python Shell Jobのバージョンアップにおける注意点
- make
- 11 分前
- 読了時間: 5分

はじめに
AWS Glueには、ジョブのタイプとして独自に作ったPythonスクリプトを実行できるPython Shell Jobというものがあります。
AWS Glueといえば、サービス概要からPySparkやScalaによるサーバレスなETL基盤提供やデータカタログをGlue Crawlerで自動生成といった主にETL周りの処理に特化したイメージがあると思います。
今回の記事で登場するPython Shell Jobの主な使いどころとしては、ETLのつなぎのちょっとした準備処理などがあるのですが、「独自に作ったPythonスクリプトを実行できる」なので、実はいろんなことに使えます。
弊社では、以下のAWS公式blog記事を参考に長時間のクエリ実行を伴うバッチJOB実行処理で採用しています。
AWS公式blog)
バージョンアップ
Python Shell Jobの提供バージョンは2025/07現在、
PythonShell 3.6(Glue バージョン 1.0でサポート)
PythonShell 3.9(Glue バージョン 3.0でサポート)
があり、このうち、PythonShell3.6は2026/03/01にサポート終了を迎えます。
Glueのバージョンの考え方は少々複雑です。
詳細は下記、公式ページを参照ください。
要約すると、
PythonShellは最新でも3.9、Pythonの最新は3.14
PythonShellの最新である3.9をサポートするAWS Glueは3.0、AWS Glueの最新は5.0
AWS Glue Python シェルジョブからの移行 で代替手段への移行方法を大々的に謳っている
なんだか廃止フラグが立っているように思えてなりませんね。
しかし、今は見なかったことにしておきましょう。
本記事では、PythonShell3.6から3.9にアップデートする際にハマったポイントと対処方法について紹介しています。
そもそも何が変わるのか?
主な変更点をサマリすると以下となります。
Pythonのバージョンがv3.6系からv3.9系にアップする。
持ち込みライブラリのパッケージ方法がegg形式はサポートされなくなり、wheel形式となる。
これはPythonとしてWheelがパッケージ方式の標準となっているため。
参考)https://python-packaging-user-guide-ja.readthedocs.io/ja/latest/wheel_egg.html
PythonShellジョブの実行環境に予めインストールされているライブラリが変わる。
参考)https://docs.aws.amazon.com/ja_jp/glue/latest/dg/add-job-python.html#python-shell-supported-library
予めインストールされているライブラリについてオプション選択できる。
「library-set」オプションとして「analytics」または「none」で指定します。
Cloudformationで指定する場合はDefaultArgumentsで以下のように指定します。
DefaultArguments: {
"--extra-py-files": "s3://bucket-name-xxxx/持ち込みライブラリのwheelファイル",
"--job-bookmark-option": "job-bookmark-disable",
"--job-language": "python",
"library-set": "analytics"
}
ハマりポイント
弊社では、冒頭にご紹介したようにDBへのクエリ実行を伴うJOBで使用していました。
変更点をみると元々提供されていたDB操作ライブラリは「PyGreSQL5.0.6」から「psycopg2 2.9.3」に変わっているようです。
そして、「psycopg2」を使用するには、「library-set=analytics」を指定するようです。
使い方には大差ないので、呼び出し方法を少し見直して共通分析ライブラリ(analytics)を指定してめでたしめでたしとなるはずでした。
ハマりポイント1:Aurora PosgreSQL接続でエラー発生
該当JOBでは、Aurora PostgreSQLへのクエリ操作を行っています。
動作確認をしたところ以下のエラーが発生しました。
SCRAM authentication requires libpq version 10 or above
このエラーが意味するところは以下の通りです。
psycopg2はC言語のPostgreSQLインタフェースライブラリであるlibpqを介してDB操作を行う仕組みであり、この依存するC言語ライブラリバージョンが古い(バージョン10未満)ため、PostgreSQLのSCRAM認証メカニズムに対応できない。
そもそもGlue側で用意されているライブラリセットでこの手のエラーが出るのはどうかと思うのでAWSサポートを介して改善要望は挙げたのですが、目先で対策を打つ必要はあります。
対処1
対応するには以下の選択肢がありそうです。
libpqバンドル版である「psycopg2-binary」のwheelファイルをpip downloadで入手してS3に置き、「extra-py-files」オプションで持ち込む。
「additional-python-module」オプションで動的にpipインストールで「psycopg2-binary」を導入する。(NATGatewayの設置などインターネットへのアウトバウンドが必要)
依存ライブラリがないPure Pythonなライブラリ(pg8000など)を持ち込んでそれで処理する。
AuroraPostgreSQLのコンフィグで認証アルゴリズムをダウングレードしてmd5などに変える。
次に挙げるNG理由により、消去法でいくと1が良さそうです。
選択肢2:もともとGlueJobはPrivateSubnetに配置しており、インターネットアウトバウンドも不要だったため、NATGatewayは設置しておらず、このためだけに設置してコスト増になるのは微妙。
選択肢3:これまで使用していたPyGreSQLもC言語依存系の仕組みであり、pg8000などPurePython製のライブラリはC言語系より処理性能が遅そう。
選択肢4:認証アルゴリズムをダウングレードするのはセキュリティ上望ましくない。
ハマりポイント2:wheelによる持ち込みは依存ファイルがあると自動入手するため、外部通信発生
psycopg2-binaryだけであればうまくいくのですが、他にも持ち込みたいライブラリ、具体的にはJinja2が有りました。
「extra-py-files」オプションでは複数指定が可能なため、Jinja2もpip downloadで入手したwheelファイルを用意して持ち込むことにしました。
ところがいざGlue Python Shell Jobを実行すると、なにやら起動時にインターネット疎通できないことが原因で延々エラーを吐いて一向に処理ができませんでした。
どうやらJinja2が依存しているMarkupSafeに関するWhlファイルをpypi.orgからダウンロードしようとしてインターネット疎通できずエラーになっているようです。
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f2b36cea940>, 'Connection to pypi.org timed out. (connect timeout=15)')': /simple/markupsafe/
:
対処2
以下の対策をすれば回避はできそうです。
依存するMarkupSafeもwheelファイルを入手
Jinja2のSource DistributionをPyPIから入手
入手したソースを解凍し、pyproject.tomlを編集して依存するライブラリの記述を削除(下記部分)
dependencies = ["MarkupSafe>=2.0"]
依存ファイルなし版のJinja2 whlファイルを作成する
pip wheel .
MarkupSafeと依存ファイルなし版のJinja2のwhlファイルを—extra-py-filesで指定する
しかし、これはかなり手間ですので、結局、以下で対処することにしました。
必要なwhlファイル群を全て1フォルダ内に配置
フォルダをzipで固め、whlファイル一式を1つのzipにする
このzipを—extra-py-filesに指定する
Glue Python Shell Job側で持ち込んだzipを解凍してwhlファイルをpip installで実行環境に自力で取り込む
import os.path
import subprocess
import sys
def get_referenced_filepath(file_name, matchFunc=os.path.isfile):
for dir_name in sys.path:
candidate = os.path.join(dir_name, file_name)
if matchFunc(candidate):
return candidate
raise Exception("Can't find file: ".format(file_name))
zip_file = get_referenced_filepath("dependencies.zip")
subprocess.run(["unzip", zip_file])
subprocess.run(["pip3 install --no-index --find-links=. -t . *.whl"], shell=True)
# 実行したいコード
:
最後に
Glue Python Shell Jobのバージョンアップ対応なんて楽勝と思っていましたが、思わぬところで色々ハマってしまいました。
しかし、詰まってしまうことで自ずと深堀りしていくことになり、色々深く知ることもでき、良い点もあったかなと前向きに捉えています。
同じ問題にあたってしまった方のお役に立てれば幸いです。
コメント