Lambdaでpython-oracledbをThickモードで利用する

OracleDBのPythonクライアントである「python-oracledb」を使用して、AWS LambdaからThickモードで接続する方法をご紹介します。 今回はLambdaレイヤーを使用し、パッケージをLambdaから読み込みます。
2022.07.31

Thickモードについて

Python OracleDBについては以下の記事が参考になると思います。

上記の記事でも書かれていますが、python-oracledbには「Thin」と「Thick」2つのモードが有り、それぞれ以下のような違いがあります。

  • Thin: 外部パッケージ不要。いくつかの機能が無い
  • Thick: OracleInstantClientが必要

詳細な違いには以下のリンクが参考になります。

ここに書かれていること以外にも、「Thin」モードではクライアントが使用できる接続情報のパラメータが使用できなかったりと、些細な違いがあったりします。

「Thick」モードを使用する場合Oracle Instant ClientというOracle社から提供されているライブラリが必要になります。

Lambdaレイヤーの作成

OracleInstantClientのダンロード先のURLを入手する

OracleInstantClientのダウンロードは以下から行えます。

今回はLambdaのパッケージサイズの上限である250MB以下にレイヤーを抑えるため、「Basic Light Package」を利用します。 今回はZIPのURLが後々必要になってくるので、メモしておいてください。

Light版の仕様は以下のURLが参考になります。

レイヤーのzipファイルの作成

Lambdaレイヤーを作成する前に、レイヤーのソースとなるzipファイルを作成します。

今回はAmazon Linxu 2を使用してレイヤーのビルドを行います。

build.sh

#! /bin/bash

# ここのURLを変更するORACLE_INSTANT_CLIENT=https://download.oracle.com/otn_software/linux/instantclient/217000/instantclient-basiclite-linux.x64-21.7.0.0.0dbru.zip
BUILD_DIR=build
mkdir -p ${BUILD_DIR}
cd ${BUILD_DIR}
mkdir -p lib
mkdir -p python

sudo yum install -y libaio
pip3 install oracledb -t python

wget ${ORACLE_INSTANT_CLIENT} -O oracle_instant_client.zip
unzip -j oracle_instant_client.zip -d lib/
cp /lib64/libaio.so.1 lib

zip -r -y oracle_layer.zip lib/ python/

rm -rf lib python oracle_instant_client.zip

上記のようなスクリプトを使用して今回は作成します。 スクリプトの実行が成功するとbuildディレクトリ以下にoracle_layer.zipというファイルが生成されるので、それをLambdaレイヤーとして使用します。

途中、libaioをインストールしているので、環境に影響を与える可能性があるため、専用のEC2インスタンスを使用してビルドすることをおすすめします。

zipファイルには以下の2つのディレクトリが存在し、以下のような役割になっています。

  • python/: Pythonのパッケージ。今回は「python-oracledb」が入っている
  • lib/: Python以外のライブラリ。/opt/libにLamba内でマウントされる。今回は「OracleInstatnClient」が入っている。

今回はこれをS3にアップロードします。

アップロード

aws s3 cp build/oracle_layer.zip s3://your-bucket/oracle_layer.zip

これで下準備は完了です。

Lambdaレイヤーの作成

今回はLambdaレイヤーを以下のような設定で作成します。

Python3.7ではうまく動作しましたが、3.8, 3.9では「python-oracledb」のインポートに失敗してしまうため、今回はこの1つのみにしてあります。 これはビルド環境のPythonのバージョンを上げて、zipファイルを作成すれば解決します。 今回は説明の簡略化のためにAmazon Linux 2のデフォルトのPythonのバージョン3.7を利用しています。

SAMなどで、「python-oracledb」をレイヤー化せずに使用する場合はInstantClientのみのレイヤーを作成してもいいかもしれません。

Thickモードの使用

先程作成したLambdaレイヤーを対象のLambda関数にアタッチした後は、以下のようにすればThickモードで利用可能です。

lambda_function.py

import oracledb
oracledb.init_oracle_client()

def lambda_handler(event, context):
    return

init_oracle_clientでThickモードを有効化できます。

終わりに

Thickモードでのpython-oracledbをLambda上で使用可能にすることができました。 Lambdaのパッケージサイズの上限の仕様でLitght Clientを使用しましたが、フルサイズを使用したい場合はコンテナランタイムを使用するなどの方法も取れると思います。

参考