Pythonを使用してSQL ServerデータベースをAlibaba Cloud Function Computeに接続する 

このドキュメントでは、SQL **Server**データベースを**Alibaba Cloud Function Compute**で使用する方法と、fc-dockerをベースにした**Function Compute**の設定と検証について説明します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/using-python-to-connect-function-compute-to-sql-server_594411)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

#テスト環境の準備
Dockerを使ってローカルのMacコンピュータでSQL Server 2017を実行し、テーブル構造を初期化し、index.pyという名前のテストファイルを作成し、データベースにアクセスできるかどうかを確認します。

```
$ docker pull mcr.microsoft.com/mssql/server:2017-latest

$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Codelife.me' \
   -p 1433:1433 --name sql1 \
   -d mcr.microsoft.com/mssql/server:2017-latest
```
ポート1433からSQL Serverを起動し、SAアカウントのパスワードを`Codelife.me`に設定します。

```
$ brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
$ brew update
$ ACCEPT_EULA=y brew install --no-sandbox msodbcsql mssql-tools
```
Homebrew を使用して、MSSQL クライアント SQLCMD をインストールします。

```
$ sqlcmd -S localhost -U SA -P 'Codelife.me'
1>CREATE DATABASE TestDB
2>SELECT Name from sys.Databases
3>GO
Name
-----------------------------------------------
master
tempdb
model
msdb
TestDB

(5 rows affected)
```

TestDBという名前のテストデータベースを作成します。

```
1> USE TestDB
2> CREATE TABLE Inventory (id INT, name NVARCHAR(50), quantity INT)
3> INSERT INTO Inventory VALUES (1, 'banana', 150); INSERT INTO Inventory VALUES (2, 'orange', 154);
4> GO
Changed database context to 'TestDB'.

(1 rows affected)

(1 rows affected)
```
インベントリという名前のテーブルを作成し、テストデータの行を挿入します。

```
1> SELECT * FROM Inventory WHERE quantity > 152;
2> GO
id          name                                               quantity
----------- -------------------------------------------------- -----------
          2 orange                                                     154

(1 rows affected)
1> QUIT
```

データが正常に挿入されたことを確認して終了します。

#テスト機能の準備

```
import pymssql

def handler(event, context):
    conn = pymssql.connect(
        host=r'docker.for.mac.host.internal',
        user=r'SA',
        password=r'Codelife.me',
        database='TestDB'
    )
    
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM inventory WHERE quantity > 152')
    
    result = ''

    for row in cursor:
        result += 'row = %r\n' % (row,)

    conn.close()
    return result
```

index.pyという名前のテスト関数を開発します。この関数は Mac ホストの `docker.for.mac.host.internal` 上の SQL Server に接続しますが、fc-docker はコンテナ内で関数を実行するため、localhost には接続しません。そして、クエリ文を実行して結果を返します。

#インストールの完了v - pymssqlの最新バージョン
空のディレクトリを作成し、その中にindex.pyファイルを配置します。コマンドセッションの現在のパスをindex.pyがあるディレクトリに切り替えます。そして、以下のコマンドを実行します。

```
$ docker run --rm --name mssql-builder -t -d -v $(pwd):/code --entrypoint /bin/sh aliyunfc/runtime-python3.6
$ docker exec -t mssql-builder pip install -t /code pymssql
$ docker stop mssql-builder
```
1、この例では、fc-dockerが提供するPython3.6のランタイム環境(aliyunfc/runtime-python3.6)を使用しています。
2、1行目は決して終了しないDockerコンテナを起動するために使用され、2行目のdocker execはコンテナに依存関係をインストールするために使用されます。最後の行は、コンテナを終了するために使用されます。ローカルパスの &dollar;(pwd) がコンテナの /code ディレクトリにマウントされていることを考えると、コンテナを終了した後、/code ディレクトリの内容は現在のローカルパスに保持されます。
3、pipはWheelパッケージを-tパラメータで/codeディレクトリにインストールします。

```
$ docker run --rm -v $(pwd):/code aliyunfc/runtime-python3.6 --handler index.handler
row = (2, 'orange', 154)


RequestId: d66496e9-4056-492b-98d9-5bf51e448174          Billed Duration: 144 ms         Memory Size: 19
```
前述のコマンドを実行します。インストール結果が返ってきます。pymssqlの以前のバージョンを使用する必要がない場合は、以下のセクションは無視してください。

#インストールの完了 - pymssqlの旧バージョン
2.1.3以前のバージョンのpymssqlの場合、pip installコマンドを実行すると、pymssqlがコンパイルされ、ソースコードからインストールされます。この場合、コンパイル依存の freetds-dev とランタイム依存の libsybdb5 をインストールします。コンパイル依存関係はシステムディレクトリに直接インストールすることができますが、実行依存関係はローカルディレクトリにインストールする必要があります。

```
docker run --rm --name mssql-builder -t -d -v $(pwd):/code --entrypoint /bin/sh aliyunfc/runtime-python3.6

docker exec -t mssql-builder apt-get install -y -d -o=dir::cache=/code libsybdb5
docker exec -t mssql-builder bash -c 'for f in $(ls /code/archives/*.deb); do dpkg -x $f $(pwd) ; done;'
docker exec -t mssql-builder bash -c "rm -rf /code/archives/; mkdir /code/lib;cd /code/lib; ln -sf ../usr/lib/x86_64-linux-gnu/libsybdb.so.5 ."
docker exec -t mssql-builder apt-get install -y freetds-dev 
docker exec -t mssql-builder pip install cython 
docker exec -t mssql-builder pip install -t /code pymssql==2.1.3

docker stop mssql-builder
```

1、1列目でコンテナを開始し、10列目でコンテナを停止して自動的に削除します。
2、2行目と3行目は、ランタイム依存のlibsybdb5をローカルディレクトリにインストールするために使用されます。
3、DLL libsybdb.so.5を、デフォルトでLD_LIBRARY_PATHに追加されている/code/libディレクトリにリンクします。
4、システムディレクトリにfreetds-devとcythonをインストールし、pymssqlのコンパイルとインストールを行います。どちらのライブラリもpymssql実行時には必要ないので、ローカルディレクトリにインストールする必要はありません。
5、 pymssql 2.1.3をインストールします。pymssql 2.1.4以降では、インストール時にソースコードが不要になりました。

```
$ docker run --rm -v $(pwd):/code aliyunfc/runtime-python3.6 --handler index.handler
row = (2, 'orange', 154)


RequestId: d66496e9-4056-492b-98d9-5bf51e448174          Billed Duration: 144 ms         Memory Size: 19
```

試験は合格しています。

#結論
このドキュメントでは、Alibaba Cloud Function Computeで[SQL Server](https://www.alibabacloud.com/ja/product/apsaradb-for-rds-sql-server)データベースを使用する方法を説明します。最新バージョンのpymssqlをインストールするためのソースコードが不要になりました。ただし、pipを使ってソースコードパッケージからpymssqlをインストールする方法は、似たようなシナリオにも適用できます。

このドキュメントでは、fc-dockerをベースとした[Function Compute](https://www.alibabacloud.com/ja/products/function-compute)の設定と検証方法についても説明しています。fcli sboxとfc-dockerの異なるファイルをスクリプトとして開発し、繰り返し実行することができ、fc-dockerはシミュレーションされたローカルランタイム環境で実行することができます。どちらの機能も、継続的インテグレーション（CI）のシナリオでは非常に便利です。

#参考文献
1、[https://pymssql.readthedocs.io/en/latest/intro.html#install](https://pymssql.readthedocs.io/en/latest/intro.html?spm=a2c65.11461447.0.0.4c5c5b92rH4ZC6#install)
2、http://www.freetds.org/
3、https://pymssql.readthedocs.io/en/latest/pymssql_examples.html
4、https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-2017
5、https://cloudblogs.microsoft.com/sqlserver/2017/05/16/sql-server-command-line-tools-for-macos-released/

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*