JINSテックブログ
🐍

Lambdaで動くpyodbcのレイヤーを作ってみた

2024/12/16に公開

この投稿は、2024年JINSのアドベントカレンダー16日目の記事です。

pyodbcを使って何がしたかったのか

今回実現したかったことはSnowflake上にあるデータの一部をSQL Serverに連携(INSERT)することでした。今まではETLツールがその役目を担っていたのですが、今年ライセンス期限を迎えることからSQL Serverが無くなるまでは自前のプログラムで乗り切ることにしました。
このプログラムはLambdaで稼働させるのですが、SQL ServerとのやりとりのためPythonライブラリのpyodbcを使用することにしました。

Lambdaレイヤーって何?

Lambda レイヤーは、補助的なコードやデータを含む .zip ファイルアーカイブです。レイヤーには通常、ライブラリの依存関係、カスタムランタイム、または設定ファイルが含まれています。

デプロイパッケージを小さくして、複数のLambda関数で使いまわせて、かつバージョン管理をして更新しても他のLambda関数に影響を与えない素敵機能がLambdaレイヤーだと思っています。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/chapter-layers.html

作成手順

Amazon Linux 2023で作成しました。
Dockerでも同じ手順で行けたので使いまわせると思います。
Linux・Lambdaで動かすにはunixODBC用soファイルとODBC driver for MSSQLファイルが必要となります。

unixODBC用soファイルのダウンロード

curl ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.7.tar.gz -O
tar xvzf unixODBC-2.3.7.tar.gz
cd unixODBC-2.3.7
./configure --sysconfdir=/opt --disable-gui --disable-drivers --enable-iconv --with-iconv-char-enc=UTF8 --with-iconv-ucode-enc=UTF16LE --prefix=/opt
make
sudo make install

ODBC driver for MSSQL 17ファイルのダウンロード

curl https://packages.microsoft.com/config/rhel/7/prod.repo | sudo tee /etc/yum.repos.d/mssql-release.repo
sudo ACCEPT_EULA=Y yum install -y msodbcsql17
sudo ACCEPT_EULA=Y yum install -y mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
export CFLAGS="-I/opt/include"
export LDFLAGS="-L/opt/lib"
sudo yum install -y unixODBC-devel

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

cd /opt
cp -r /opt/microsoft/msodbcsql17/ .
rm -rf /opt/microsoft/

mkdir /opt/python/
cd /opt/python/
pip install pyodbc -t .

cd /opt
cat <<EOF > odbcinst.ini
[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/msodbcsql17/lib64/libmsodbcsql-17.10.so.6.1
UsageCount=1
EOF

cat <<EOF > odbc.ini
[ODBC Driver 17 for SQL Server]
Driver = ODBC Driver 17 for SQL Server
Description = My ODBC Driver 17 for SQL Server
Trace = No
EOF

cd /opt
zip -r9 ~/pyodbc-layer.zip .

上記で作成したzipファイルを使ってLambdaレイヤーを作成すればレイヤー作成完了です。

詰まりポイント

上記の手順で作ったレイヤーでLambda関数を動かすことに成功したのですが、これを作るまでに躓いたポイントを記載しておきます。

1. Windows環境でDockerを使用せずに作成する

libodbc.so.2: cannot open shared object file: No such file or directory",

Windows環境でpyodbcだけpip installして稼働確認出来た!でそのままレイヤー用のzipファイルを作ってもうまくいかない。WindowsだとODBCドライバーが入っているが、Lambdaで動かすためには追加で同梱させてあげる必要があった。

2. 複数台あるSQL Serverのうち、一部だけ繋がらない

('08001', '[08001] [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: Error code 0x2746 (10054) (SQLDriverConnect)'

古いSQL Serverと接続するとき、TLSの互換性を高めるためopensslの設定を行う必要があった。Lambdaだと上手く回避出来なかったので、とりあえずEC2上で下記の設定を行い回避しました。

  • openssl.cnf
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=0

まとめ

上記の設定方法でLambdaレイヤーをつくってptodbcライブラリを使用することが出来ました。
特にバージョニングをしてくれることで、レイヤー側に変更を加えるときも既存のLambda関数に影響を与えないので今後作る時もレイヤーは積極的に使用しようと思います。

SQL Serverへの連携では単純なINSERT時はすぐ出来るようになったものの、型問題など次々遭遇するトラブルを解決していったのでまた書く機会があれば。

今回はレガシーシステムを救う後ろ向き開発でしたが、未来に向けた取り組みも進めていきますのでそちらもまたいずれご紹介できればと思います!

JINSテックブログ
JINSテックブログ

Discussion