简体   繁体   English

AWS Lambda 使用 Python 和 pyodbc 连接到 SQL

[英]AWS Lambda connecting to SQL with Python and pyodbc

I have an AWS Lambda that I want to connect to my on prem SQL server to read and write data from\\to.我有一个 AWS Lambda,我想连接到我的本地 SQL 服务器以从\\到读取和写入数据。 I am using Python and pyodbc.我正在使用 Python 和 pyodbc。 I have got pyodbc installed (compiled zip file in an S3 bucket added to the lambda through a layer), but when I try and run this code I get an odd error:我已经安装了 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()

This is the error:这是错误:

[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)

All I'm finding online is people who are unable to get the pyodbc library installed in the first place, so having got past that sticking point I thought I was free and clear.我在网上找到的只是那些一开始就无法安装 pyodbc 库的人,所以过了那个症结后,我以为我是自由而清晰的。 Can anyone explain what I've run into now?谁能解释一下我现在遇到了什么?

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

AWS didn't recognise .tar.gz files, so I changed it to a zip file and also added in the folder structure which another googled site told me was necessary: \\python\\lib\\python3.7\\site-packages\\pyodbc that folder contains: libodbc.so.2 pyodbc.so AWS 无法识别 .tar.gz 文件,因此我将其更改为 zip 文件,并添加到另一个 googled 站点告诉我的文件夹结构中:\\python\\lib\\python3.7\\site-packages\\pyodbc文件夹包含:libodbc.so.2 pyodbc.so

I uploaded this Zip file to an S3 bucket and pointed a Lambda layer at it.我将此 Zip 文件上传到 S3 存储桶并指向它的 Lambda 层。

Have I done something silly with this?我做了什么傻事吗?

From your description, I believe you may have gotten your folder structure wrong. 根据您的描述,我相信您可能误解了文件夹结构。

If you were to look in your zip file, you should see the following structure: 如果要查看zip文件,则应该看到以下结构:

layerZip.zip
└ python
  └ lib
    └ python3.7
      └ site-packages
        └ pyodbc

But I believe you may actually have 但是我相信你可能真的有

layerZip.zip
└ \
  └ python
    └ lib
      └ python3.7
        └ site-packages
          └ pyodbc

But honestly, just use this structure: 但老实说,只需使用以下结构:

layerZip.zip
└ python
  └ pyodbc

It'll work just as well, it's just setting the module up as global instead of per user. 它也可以正常工作,只是将模块设置为全局模块,而不是每个用户。

I had the same issue. 我遇到过同样的问题。 You must use correct version of python when building the package to upload to lambda. 构建要上传到lambda的软件包时,必须使用正确版本的python。

I did a 'pip install pyodbc -t .' 我做了一个'pip install pyodbc -t'。

It placed the following: 它放置了以下内容:

drwxr-xr-x 2 root root   4096 Sep 20 21:29 pyodbc-4.0.27.dist-info
-rwxr-xr-x 1 root root 658704 Sep 20 21:29 pyodbc.cpython-36m-x86_64-linux-gnu.so

The lib is very specific to the version of python. lib非常特定于python版本。 In the file name,'-36m-', so it will work the lambda python 3.6 environment. 在文件名“ -36m-”中,因此它将在lambda python 3.6环境下工作。

My initial issue was I was using lambci/lambda:build-python3.7 for my docker environment. 我最初的问题是我在docker环境中使用了lambci / lambda:build-python3.7。 So pyodbc installed the python 3.7 version of the library, '-37m-'. 因此,pyodbc安装了库python 3.7版本“ -37m-”。

Since lambda was looking for the 3.6 version it did not see the 3.7 version. 由于lambda正在寻找3.6版本,因此没有看到3.7版本。

I switched to using lambci/lambda:build-python3.6 and all was better. 我改用lambci / lambda:build-python3.6,一切都更好。

I followed this article for getting everything working: 我关注了这篇文章,以确保一切正常:

https://medium.com/faun/aws-lambda-microsoft-sql-server-how-to-66c5f9d275ed https://medium.com/faun/aws-lambda-microsoft-sql-server-how-to-66c5f9d275ed

Notable Points值得注意的点

  • The environment in which you build the layer should be the same as your Lambda function runtime environment.您构建层的环境应该与您的 Lambda 函数运行时环境相同。 ie. IE。 if you build the package in a python3.7 environment then lambda should be launched with the python 3.7 runtime.如果您在 python3.7 环境中构建包,那么 lambda 应该与 python 3.7 运行时一起启动。

Guidance from AWS Support AWS Support 的指导

pyodbc is distributed in a shared lib format (which can be a little challenging to compile for lambda). pyodbc 以共享库格式分发(为 lambda 编译可能有点困难)。 It also requires other shared libs such as unixODBC (connector which the wrapper works around) and also the database drivers (in this case we will be using msodbcsql17).它还需要其他共享库,例如 unixODBC(包装器工作的连接器)以及数据库驱动程序(在这种情况下,我们将使用 msodbcsql17)。

The folder structure for this layer should look like this:该层的文件夹结构应如下所示:

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

In order to generate this layer, you need to execute the following steps:为了生成这个层,你需要执行以下步骤:

  1. create an EC2 Ubuntu 18.04 LTS instance (t2.micro is fine) and SSH into it.创建一个 EC2 Ubuntu 18.04 LTS 实例(t2.micro 很好)并通过 SSH 连接到它。

  2. Install docker using snap with the following command: sudo snap install docker通过以下命令使用 snap 安装 docker: sudo snap install docker

  3. Run the following command to create a container based on amazon linux with python3.7 as it's environment.运行以下命令,创建一个基于amazon linux 的容器,环境为python3.7。 Keep in mind that you can change to python 3.6 just by changing build-python3.7 to build-python3.6.请记住,您可以通过将 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
  1. When you fist run this command, docker will download the amazon linux image from dockerhub (it may take 30-60 seconds to download and unpack it).当你第一次运行这个命令时,docker 会从 dockerhub 下载 amazon linux 镜像(下载和解压可能需要 30-60 秒)。 After you download it, you will enter the docker's image bash (In case you weren't redirected to the dockers bash, just run the command again)下载后,您将进入docker的图像bash(如果您没有重定向到dockers bash,只需再次运行该命令)

  2. After you are in the docker's bash, copy and paste the following commands to your docker:在您进入 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 .

(In case you get errors related to "read-only file system" just exit the docker shell by using the command "exit" and try the steps again) (如果您遇到与“只读文件系统”相关的错误,只需使用“exit”命令退出 docker shell 并重试这些步骤)

  1. Now make sure you exit your container using the command:现在确保使用以下命令退出容器:
exit
  1. Now the file will be available in the folder "/home/ubuntu".现在该文件将在文件夹“/home/ubuntu”中可用。 You can upload it using AWS CLI (if you have it configured) or retrieve via Sftp.您可以使用 AWS CLI(如果已配置)上传或通过 Sftp 检索。 In case you are going to use cyberduck/winscp/fillezilla or even sftp shell, you will need to change permissions on the file in order to download it.如果您打算使用 Cyber​​duck/winscp/fillezilla 甚至 sftp shell,您将需要更改文件的权限才能下载它。

The fastest way to give the file permission to be downloaded is using the following line:授予要下载的文件权限的最快方法是使用以下行:

sudo chmod o+rw pyodbc-layer.zip
  1. Now you can retrieve it using sftp or any sftp-compatible client.现在您可以使用 sftp 或任何与 sftp 兼容的客户端来检索它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM