python 連接配接資料庫通常要安裝第三方子產品,連接配接 MS SQL Server 需要安裝 pymssql 。由于 pymsql 依賴于 FreeTDS
,對于先于 2.1.3 版本的 pymssql,需要先安裝 FreeTDS。由于早期版本的 pymssql 隻提供了 windows 下的 wheel 打包,其他平台(如 linux)需要從源碼包編譯安裝,那需要先安裝 freetds-dev 包,以提供必要的頭檔案。
函數計算的 runtime 運作時的目錄是隻讀的,是以對于需要使用 apt-get 和 pip 安裝依賴的場景,需要将依賴安裝在代碼目錄而不是系統目錄。具體安裝方法可以參考
《函數計算安裝依賴庫方法小結》。而 pymssql 的老版本涉及到編譯安裝,比常見的二級制安裝到本地目錄略複雜一些。
函數計算依賴安裝需要有個模拟的 linux 環境,從前我們推薦使用 fcli shell 的 sbox ,啟動一個接近生産環境的 docker container 進行依賴安裝。因為有些依賴是平台相關的,在 mac 系統安裝的動态連結庫無法在函數計算的 linux 環境下運作, pymssql 恰好屬于這種情況。本文我将使用
fc-docker進行安裝和本地測試。
下面的例子是基于函數計算 runtime python3.6 的,對于 python2.7 也進行了測試,同樣适用。
準備測試環境
首先使用 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
将 SQL Server 啟動于 1433 端口,并設定 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)
建立一張 Inventory 表,并參入一行測試資料。
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
(這裡不能是 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
- 這裡使用了 fc-docker 提供的 python3.6 的模拟環境:aliyunfc/runtime-python3.6
- 第一行啟動了一個不會退出的 docker container,第二行使用 docker exec 進入這個 container 安裝依賴,最後一行退出該 container。因為本地路徑 $(pwd) 被挂載到 container 内部的 /code 目錄,是以 container 退出以後 /code 目錄的内容還會保留在本地目前路徑下。
- 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
- 第一行啟動一個 container,第十行停止并自動删除該 container。
- 第二行至第三行将運作時依賴 libsybdb5 安裝于本地目錄。
- 将動态連結庫 libsybdb.so.5 連結到目錄 /code/lib 目錄下,因為該目錄預設配置到了環境變量 LD_LIBRARY_PATH 下。
- 将 freetds-dev 和 cython 安裝到系統目錄,用于 pymssql 編譯安裝,因為運作時 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
測試通過。
小結
這是一份來遲的函數計算使用 sql server 資料庫的配置文檔。目前版本的 pymssql 已經不再需要源碼安裝了。但是 pip 源碼包安裝的方法,對于其他類似的場景也是适用的。
本文也提供了一種基于 fc-docker 的配置和調試方法,不同 fcli 的 sbox,fc-docker 可以寫成腳本反複執行,并且也可以用于本地模拟執行,對于 CI 場景非常有幫助。
參考閱讀
- http://www.pymssql.org/en/latest/intro.html#install
- http://www.freetds.org/
- http://www.pymssql.org/en/stable/pymssql_examples.html
- https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-2017
- https://cloudblogs.microsoft.com/sqlserver/2017/05/16/sql-server-command-line-tools-for-macos-released/