函數計算 Python 鏈接 SQL Server 小結

摘要: python 鏈接數據庫一般要安裝第三方模塊,鏈接 MS SQL Server 須要安裝 pymssql 。因爲 pymsql 依賴於 FreeTDS,對於先於 2.1.3 版本的 pymssql,須要先安裝 FreeTDS。html

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

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

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

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

準備測試環境

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

$ 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.medocker

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

$ 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 表,並參入一行測試數據。macos

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
  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/

原文連接

相關文章
相關標籤/搜索