在Lambda中构建pymssql(FreeTDS)的完整指南

本文详细介绍了如何在AWS Lambda环境中构建pymssql/FreeTDS连接层,包含完整的Dockerfile配置、本地测试方法和docker-compose部署方案,解决Python连接MSSQL数据库的技术难题。

在Lambda中构建pymssql(FreeTDS)

正如我在之前的文章中讨论过的,在Lambda中使用Python连接MSSQL可能会很棘手。虽然我之前已经用pyodbc解决了这个问题,但使用pymssql/FreeTDS是另一个选择,我想同样分享创建相应Lambda层的构建过程。

多阶段Dockerfile配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
FROM public.ecr.aws/lambda/python:3.9 as builder

ENV FREETDS_VERSION=1.3.9
ENV INSTALLDIR='/tmp/freetds'

RUN yum update -y
RUN yum install wget tar gzip zip gcc make gcc gcc-c++ python39-devel unixODBC-devel -y

RUN mkdir $INSTALLDIR build

RUN wget ftp://ftp.freetds.org/pub/freetds/stable/freetds-${FREETDS_VERSION}.tar.gz && \
    tar -xzf freetds-${FREETDS_VERSION}.tar.gz && \
    cd freetds-${FREETDS_VERSION} && \
    ./configure --prefix=${INSTALLDIR} --with-tdsver=7.3 && \
    make && \
    make install

ENV CPPFLAGS="-I/usr/include/python3.9m"
RUN pip install --upgrade pip
RUN mkdir /opt/python/ && pip install pymssql -t /opt/python

FROM public.ecr.aws/lambda/python:3.9
COPY --from=builder /opt/python /opt/python

Lambda层构建

与前一篇文章类似,您可以通过构建镜像并运行copy命令将依赖项提取到本地文件系统:

1
2
docker build -t pymssql-3-9 .
docker run --rm --entrypoint bash -v $PWD:/local pymssql-3-9 -c "cp -R /opt /local"

构建和部署层所需的所有内容现在都在./opt目录中。

本地测试

我们可以使用MSSQL容器在本地测试。首先添加一个本地app.py脚本作为上面Lambda容器中的处理程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import os
import pymssql

DB_HOST = "db"
DB_USER = "sa"
DB_PASSWORD = os.getenv("SA_PASSWORD")
DB_NAME = "master"


def handler(event, context=None):
    sql = "SELECT @@VERSION"

    with pymssql.connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) as conn:
        with conn.cursor() as cursor:
            cursor.execute(sql)
            return str(list(cursor)[0])
    return False

这些可以通过docker-compose.yml文件连接起来:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: "3.9"

services:
  db:
    image: mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04
    ports:
      - "1433:1433"
    environment:
      SA_PASSWORD: "Your_password123"
      ACCEPT_EULA: "Y"
  lambda:
    ports:
      - "9000:8080"
    environment:
      SA_PASSWORD: "Your_password123"
    volumes:
      - "$PWD/app.py:/var/task/app.py"
    command:
      - app.handler
    build:
      context: .
      dockerfile: ./Dockerfile
    depends_on:
      - db
  invoke:
    depends_on:
      - lambda
    image: alpine/curl:3.14
    entrypoint: >
      /bin/sh -c "sleep 10 && curl -X POST 'http://lambda:8080/2015-03-31/functions/function/invocations' -d '{}'"

10秒后,invoke容器将对Lambda处理程序运行HTTP POST。您应该看到如下输出:

1
2
3
4
5
lambda_1  | START RequestId: 9f5d1fcc-280a-4a36-8d00-bb192b9e58c6 Version: $LATEST
lambda_1  | END RequestId: 9f5d1fcc-280a-4a36-8d00-bb192b9e58c6
lambda_1  | REPORT RequestId: 9f5d1fcc-280a-4a36-8d00-bb192b9e58c6	Init Duration: 0.21 ms	Duration: 89.99 ms	Billed Duration: 90 ms	Memory Size: 3008 MB	Max Memory Used: 3008 MB	
100   202  100   200  100     2   2185     21 --:--:-- --:--:-- --:--:--  2195
invoke_1  | "('Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64) \\n\\tSep 24 2019 13:48:23 \\n\\tCopyright (C) 2019 Microsoft Corporation\\n\\tDeveloper Edition (64-bit) on Linux (Ubuntu 16.04.6 LTS) <X64>',)"python3-9-pymssql_invoke_1 exited with code 0

如您所见,Lambda能够成功连接到MSSQL容器并运行SELECT @@VERSION查询。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计