函數計算 Python 鏈接 SQL Server 小結

python 鏈接數據庫一般要安裝第三方模塊,鏈接 MS SQL Server 須要安裝 pymssql 。因爲 pymsql 依賴於 FreeTDS,對於先於 2.1.3 版本的 pymssql,須要先安裝 FreeTDS。因爲早期版本的 pymssql 只提供了 windows 下的 wheel 打包,其餘平臺(如 linux)須要從源碼包編譯安裝,那須要先安裝 freetds-dev 包,以提供必要的頭文件。html

函數計算的 runtime 運行時的目錄是隻讀的,因此對於須要使用 apt-get 和 pip 安裝依賴的場景,須要將依賴安裝在代碼目錄而不是系統目錄。具體安裝方法能夠參考《函數計算安裝依賴庫方法小結》。而 pymssql 的老版本涉及到編譯安裝,比常見的二級制安裝到本地目錄略複雜一些。python

函數計算依賴安裝須要有個模擬的 linux 環境,從前咱們推薦使用 fcli shell 的 sbox ,啓動一個接近生產環境的 docker container 進行依賴安裝。由於有些依賴是平臺相關的,在 mac 系統安裝的動態連接庫沒法在函數計算的 linux 環境下運行, pymssql 剛好屬於這種狀況。本文我將使用 fc-docker 進行安裝和本地測試。linux

下面的例子是基於函數計算 runtime python3.6 的,對於 python2.7 也進行了測試,一樣適用。git

準備測試環境

首先使用 docker 在本機 Mac 電腦下運行一個 SQL Server 2017 服務,並初始化表結構,編輯一個 index.py 的測試文件,以驗證數據庫訪問是否成功。github

$ 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

將 SQL Server 啓動於 1433 端口,並設定 SA 帳戶密碼爲 Codelife.mesql

$ 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。docker

$ 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。shell

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)

建立一張 Inventory 表,並參入一行測試數據。數據庫

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

(1 rows affected)
1> QUIT

驗證一下插入結果並退出。macos

準備一個測試函數

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 (這裏不能是 localhost,由於 fc-docker 會將函數運行在 container 內部)的 SQL Server 服務。執行一個查詢,並把結果返回出來。

最新版的 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. 第一行啓動了一個不會退出的 docker container,第二行使用 docker exec 進入這個 container 安裝依賴,最後一行退出該 container。由於本地路徑 $(pwd) 被掛載到 container 內部的 /code 目錄,因此 container 退出之後 /code 目錄的內容還會保留在本地當前路徑下。
  3. pip 經過 -t 參數將 wheel 包安裝在 /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 會觸發源碼編譯安裝,對於這種狀況,須要安裝編譯時依賴的 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. 第一行啓動一個 container,第十行中止並自動刪除該 container。
  2. 第二行至第三行將運行時依賴 libsybdb5 安裝於本地目錄。
  3. 將動態連接庫 libsybdb.so.5 連接到目錄 /code/lib 目錄下,由於該目錄默認配置到了環境變量 LD_LIBRARY_PATH 下。
  4. 將 freetds-dev 和 cython 安裝到系統目錄,用於 pymssql 編譯安裝,由於運行時 pymssql 不須要這兩個庫,因此無需安裝在本地目錄
  5. 安裝 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

測試經過。

小結

這是一份來遲的函數計算使用 sql server 數據庫的配置文檔。當前版本的 pymssql 已經再也不須要源碼安裝了。可是 pip 源碼包安裝的方法,對於其餘相似的場景也是適用的。

本文也提供了一種基於 fc-docker 的配置和調試方法,不一樣 fcli 的 sbox,fc-docker 能夠寫成腳本反覆執行,而且也能夠用於本地模擬執行,對於 CI 場景很是有幫助。

參考閱讀

  1. http://www.pymssql.org/en/latest/intro.html#install
  2. http://www.freetds.org/
  3. http://www.pymssql.org/en/stable/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/


本文做者:倚賢

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索