AWS Lambda 使用 Python 和 pyodbc 连接到 SQL

Mat*_*nds 4 pyodbc python-3.x aws-lambda

我有一个 AWS Lambda,我想连接到我的本地 SQL 服务器以读取和写入数据。我正在使用 Python 和 pyodbc。我已经安装了 pyodbc(在 S3 存储桶中编译的 zip 文件通过一层添加到 lambda),但是当我尝试运行此代码时,我收到一个奇怪的错误:

import boto3
import pyodbc

s3 = boto3.client('s3')

def lambda_handler(event, context):
    # print(help(pyodbc))
    server = "Server"
    database = "Database"
    username = "AWS-Lamdba-RO"
    password = "Password"
    cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
    cursor = cnxn.cursor()
Run Code Online (Sandbox Code Playgroud)

这是错误:

[ERROR] AttributeError: module 'pyodbc' has no attribute 'connect' Traceback (most recent call last):   File "/var/task/lambda_function.py", line 13, in lambda_handler     cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
Run Code Online (Sandbox Code Playgroud)

我在网上找到的都是那些无法首先安装 pyodbc 库的人,所以在克服了这个症结之后,我认为我是自由和清晰的。谁能解释一下我现在遇到了什么?

我从这里得到了 pyodbc: https://github.com/Miserlou/lambda-packages/tree/master/lambda_packages/pyodbc

AWS无法识别.tar.gz文件,因此我将其更改为zip文件,并添加了另一个谷歌搜索站点告诉我必要的文件夹结构:\python\lib\python3.7\site-packages\pyodbc文件夹包含:libodbc.so.2 pyodbc.so

我将此 Zip 文件上传到 S3 存储桶,并将 Lambda 层指向它。

我为此做了什么愚蠢的事吗?

小智 6

值得注意的点

  • 您构建层的环境应与您的 Lambda 函数运行时环境相同。IE。如果您在 python3.7 环境中构建包,则应使用 python 3.7 运行时启动 lambda。

AWS 支持的指导

pyodbc 以共享库格式分发(为 lambda 编译可能有点困难)。它还需要其他共享库,例如 unixODBC(包装器工作的连接器)以及数据库驱动程序(在本例中我们将使用 msodbcsql17)。

该层的文件夹结构应如下所示:

|-- pyodbc-layer
    |-- bin
    |-- include
    |-- lib
    |-- odbc.ini
    |-- ODBCDataSources
    |-- odbcinst.ini
    |-- python
        |-- pyodbc-4.0.26.dist-info
        |-- pyodbc.cpython-37m-x86_64-linux-gnu.so
    |-- share
Run Code Online (Sandbox Code Playgroud)

为了生成该层,您需要执行以下步骤:

  1. 创建一个 EC2 Ubuntu 18.04 LTS 实例(t2.micro 很好)并通过 SSH 连接到其中。

  2. 使用 snap 使用以下命令安装 docker: sudo snap install docker

  3. 运行以下命令,创建一个基于 amazon linux 的容器,环境为 python3.7。请记住,只需将 build-python3.7 更改为 build-python3.6 即可更改为 python 3.6。

sudo docker run -it --rm -iv${PWD}:/host-volume --entrypoint bash -e ODBCINI=/opt/odbc.ini -e ODBCSYSINI=/opt/ lambci/lambda:build-python3.7
Run Code Online (Sandbox Code Playgroud)
  1. 当您首次运行此命令时,docker 将从 dockerhub 下载 amazon linux 映像(下载和解压可能需要 30-60 秒)。下载后,您将进入 docker 的镜像 bash(如果您没有重定向到 dockers bash,只需再次运行该命令)

  2. 进入 docker 的 bash 后,将以下命令复制并粘贴到 docker 中:

curl ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.7.tar.gz  -O
tar xzvf unixODBC-2.3.7.tar.gz
cd unixODBC-2.3.7

./configure --sysconfdir=/opt --disable-gui --disable-drivers --enable-iconv --with-iconv-char-enc=UTF8 --with-iconv-ucode-enc=UTF16LE --prefix=/opt
make
make install

cd ..
rm -rf unixODBC-2.3.7 unixODBC-2.3.7.tar.gz

curl https://packages.microsoft.com/config/rhel/6/prod.repo  > /etc/yum.repos.d/mssql-release.repo
yum install e2fsprogs.x86_64 0:1.43.5-2.43.amzn1 fuse-libs.x86_64 0:2.9.4-1.18.amzn1 libss.x86_64 0:1.43.5-2.43.amzn1
ACCEPT_EULA=Y yum install msodbcsql17 --disablerepo=amzn*
export CFLAGS="-I/opt/include"
export LDFLAGS="-L/opt/lib"

cd /opt
cp -r /opt/microsoft/msodbcsql17/ .
rm -rf /opt/microsoft/

mkdir /opt/python/
cd /opt/python/
pip install pyodbc -t .

cd /opt
cat <<EOF > odbcinst.ini
[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/msodbcsql17/lib64/libmsodbcsql-17.7.so.2.1
UsageCount=1
EOF

cat <<EOF > odbc.ini
[ODBC Driver 17 for SQL Server]
Driver = ODBC Driver 17 for SQL Server
Description = My ODBC Driver 17 for SQL Server
Trace = No
EOF

cd /opt
zip -r9 ~/pyodbc-layer.zip .
Run Code Online (Sandbox Code Playgroud)

(如果您遇到与“只读文件系统”相关的错误,只需使用命令“exit”退出 docker shell,然后重试这些步骤)

  1. 现在确保使用以下命令退出容器:
exit
Run Code Online (Sandbox Code Playgroud)
  1. 现在该文件将在文件夹“/home/ubuntu”中可用。您可以使用 AWS CLI 上传它(如果您已配置)或通过 Sftp 检索。如果您要使用 cyberduck/winscp/fillezilla 甚至 sftp shell,则需要更改文件的权限才能下载它。

授予文件下载权限的最快方法是使用以下行:

sudo chmod o+rw pyodbc-layer.zip
Run Code Online (Sandbox Code Playgroud)
  1. 现在您可以使用 sftp 或任何与 sftp 兼容的客户端检索它。