简体   繁体   English

AWS Lambda function 连接到 SQL 服务器与 ZA7F5F35426B9274173FC9231B563

[英]AWS Lambda function to connect to SQL Server with Python

I've been stuck trying to connect to an SQL Server using AWS Lambda functions for a long while now.很长一段时间以来,我一直在尝试使用 AWS Lambda 功能连接到 SQL 服务器。

To do so i'm trying to use any library (tried with pyodbc, pypyodbc, etc), packaging everything into a zip file and uploading the code.为此,我尝试使用任何库(尝试使用 pyodbc、pypyodbc 等),将所有内容打包到 zip 文件中并上传代码。

The code is pretty much the same for every library, but the errors are different.每个库的代码几乎相同,但错误不同。

The code:编码:

import pypyodbc

def lambda_handler(event, context):
    conn = pypyodbc.connect('DRIVER={SQL Server};'
                      'SERVER=1.1.1.1;'
                      'DATABASE=dbname;'
                      'UID=user;'
                      'PWD=pwd')

    cur = conn.cursor()

    cur.execute("SELECT * FROM Table")

    item_count = 0

    for row in cur:
        item_count += 1

    print(item_count)

    cur.close()
    conn.close()

    return item_count

Common issues that i have covered: - I'm adding to the zip the project contents, not the folder.我讨论过的常见问题: - 我在 zip 中添加了项目内容,而不是文件夹。 - I'm also adding to the zip file the libraries needed for the code to run. - 我还将代码运行所需的库添加到 zip 文件中。

If i try to use pyodbc , the zip i'm uploading looks like this:如果我尝试使用 pyodbc ,我上传的 zip 看起来像这样:

.idea (dir)
pyodbc (dir)
lambda_function.py
pyodbc.pyd

The error i get:我得到的错误:

Unable to import module 'lambda_function': No module named pyodbc

After searching for quite a while about this, i couldn't find anything that helps.在搜索了很长一段时间后,我找不到任何有帮助的东西。 Only one comment that said that pyodbc needed to be instaled on a linux enviroment for the lambda function to work.只有一条评论说 pyodbc 需要安装在 lambda function 的 linux 环境中才能工作。 But i don't have that Enviroment available, also i don't know if that will fix this.但是我没有那个环境可用,我也不知道这是否能解决这个问题。

If i try to use pypyodbc , the zip i'm uploading looks like this:如果我尝试使用 pypyodbc ,我上传的 zip 看起来像这样:

图片

The error i get:我得到的错误:

module initialization error: 'ODBC Library is not found. Is LD_LIBRARY_PATH set?'

For this one i tried to install multiple python packages suggested by other stackoverflow posts (python-pyodb, unixodbc), but i failed every time.为此,我尝试安装其他 stackoverflow 帖子(python-pyodb、unixodbc)建议的多个 python 软件包,但每次都失败。

Then there was one comment around saying "Make sure to put native ODBC libraries under the lib folder in your zip deployment package"然后有一条评论说“确保将本机 ODBC 库放在 zip 部署包中的 lib 文件夹下”

Maybe that is some help?也许这是一些帮助? I don't know how to get native ODBC libraries..我不知道如何获得本机 ODBC 库..

Oh and one last thing.哦,还有最后一件事。 Both libraries work if i run them from my local machine.如果我从本地机器运行它们,这两个库都可以工作。 I can get access to the target server.我可以访问目标服务器。 It fails if i do it from the lambda function.如果我从 lambda function 执行此操作,它将失败。

Hopefully someone can help me and, apparently, the whole internet with this.希望有人可以帮助我,显然,整个互联网都可以帮助我。

  • you need to know Lambda copy your function in local /var/task/你需要知道 Lambda 在本地 /var/task/ 中复制你的函数
  • create a instance using Lambda official AMI https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html使用 Lambda 官方 AMI https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html创建实例
  • start instance, login启动实例,登录
  • yum install gcc gcc-c++
  • go in to /home/ec2-user进入 /home/ec2-user
  • Download the last unixodbc manager from: ftp://ftp.unixodbc.org/pub/unixODBC/从以下位置下载最后一个 unixodbc 管理器: ftp ://ftp.unixodbc.org/pub/unixODBC/
  • wget ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.5.tar.gz
  • tar xvzf unixODBC-2.3.5.tar.gz
  • cd unixODBC-2.3.5
  • configure it with the correct sysconfdir value使用正确的 sysconfdir 值配置它

    ./configure --sysconfdir=/var/task --disable-gui --disable-drivers --enable-iconv --with-iconv-char-enc=UTF8 --with-iconv-ucode-enc=UTF16LE --prefix=/home

  • make install
  • Go to /home dir and copy bin,include,lib,share directory on your computer where the Lambda project is (ex: C:\AWS\Lambda\sql_query)转到 /home 目录并复制 Lambda 项目所在计算机上的 bin,include,lib,share 目录(例如:C:\AWS\Lambda\sql_query)
  • install on your EC2 instance the the Microsoft driver libmsodbcsql-13.1.so.9.1 and then copy the driver file on your PC local directory (ex: C:\AWS\Lambda\sql_query\msodbcsql\msodbcsql\lib64 )在您的 EC2 实例上安装 Microsoft 驱动程序 libmsodbcsql-13.1.so.9.1,然后将驱动程序文件复制到您的 PC 本地目录(例如:C:\AWS\Lambda\sql_query\msodbcsql\msodbcsql\lib64)
  • Take a look https://blogs.msdn.microsoft.com/sqlnativeclient/2017/02/04/odbc-driver-13-1-for-linux-released/看看https://blogs.msdn.microsoft.com/sqlnativeclient/2017/02/04/odbc-driver-13-1-for-linux-released/
  • On your computer, in the same root directory create file odbcinst.ini在您的计算机上,在同一根目录中创建文件 odbcinst.ini

[ODBC Driver 13 for SQL Server] Description=Microsoft ODBC Driver 13 for SQL Server Driver=/var/task/msodbcsql/msodbcsql/lib64/libmsodbcsql-13.1.so.9.1 UsageCount=1

  • On your computer, in the same root directory create file odbc.ini在您的计算机上,在同一根目录中创建文件 odbc.ini

    [ODBC Driver 13 for SQL Server] Driver = ODBC Driver 13 for SQL Server Description = My ODBC Driver 13 for SQL Server Trace = No

  • on your python program use pyodbc:在你的 python 程序上使用 pyodbc:

    import pyodbc def lambda_handler(event, context): server = "xxxxxxxxxxxxxxxxxxxx" database = "xxxxxxxxxxxxxxxxxxxx" username = "xxxxxxxxxxxxxxxxxxxx" password = "xxxxxxxxxxxxxxxxxxxx" cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password) cursor = cnxn.cursor() ...other things....

  • and now play the game !现在玩游戏!

Here's a Python 3.9 solution that uses Docker and Lambda layers .这是一个使用DockerLambda 层的 Python 3.9 解决方案。

See this Github gist comment .请参阅此 Github 要点评论

Based on:基于:

  1. Create this Dockerfile :创建这个Dockerfile

     # Dockerfile # See https://stackoverflow.com/a/72617192/58876 FROM amazon/aws-lambda-python:3.9 ENTRYPOINT [] WORKDIR /root # Get development tools to enable compiling RUN yum -y update RUN yum -y groupinstall "Development Tools" # Get unixODBC and install it RUN yum -y install tar gzip RUN curl ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.11.tar.gz -O RUN tar xvzf unixODBC-2.3.11.tar.gz WORKDIR /root/unixODBC-2.3.11 RUN ./configure --sysconfdir=/opt/python --disable-gui --disable-drivers --enable-iconv --with-iconv-char-enc=UTF8 --with-iconv-ucode-enc=UTF16LE --prefix=/home RUN make install WORKDIR /root RUN mv /home/* . RUN mv unixODBC-2.3.11 unixODBC-2.3.11.tar.gz /tmp # Install msodbcsql RUN curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo RUN yum -y install e2fsprogs openssl RUN ACCEPT_EULA=Y yum -y install msodbcsql mssql-tools --disablerepo=amzn* RUN cp -r /opt/microsoft/msodbcsql . # Install pyodbc # Need "unixODBC-devel" to avoid "src/pyodbc.h:56:10: fatal error: sql.h: No such file or directory" during pip install RUN yum -y install unixODBC-devel RUN export CFLAGS="-I/root/include" RUN export LDFLAGS="-L/root/lib" RUN pip install pyodbc adodbapi pyDes --upgrade -t . # Create odbc.ini and odbcinst.ini RUN echo $'[ODBC Driver 17 for SQL Server]\nDriver = ODBC Driver 17 for SQL Server\nDescription = My ODBC Driver 17 for SQL Server\nTrace = No' > /root/odbc.ini RUN echo $'[ODBC Driver 17 for SQL Server]\nDescription = Microsoft ODBC Driver 17 for SQL Server\nDriver = /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.9.so.1.1\nUsageCount = 1' > /root/odbcinst.ini # Generate the zipped file that can be uploaded as a Lambda Layer RUN mkdir -p /opt/python RUN cp -r /root/* /opt/python RUN mv /opt/python/lib /opt RUN mv /opt/python/bin /opt WORKDIR /opt RUN zip -r /pyodbc.zip .
  2. Build the Dockerfile and extract the resulting zip file:构建 Dockerfile 并提取生成的 zip 文件:

     # Build the image (this will take a while...) $ docker build --platform=linux/amd64 -t mssql-lambda . # Copy the zipped file to /tmp/pyodbc.zip on your computer $ docker run --platform=linux/amd64 --rm --volume /tmp:/local-folder mssql-lambda cp /pyodbc.zip /local-folder/
  3. Upload /tmp/pyodbc.zip from your computer to AWS as a Lambda Layer. /tmp/pyodbc.zip作为 Lambda 层从您的计算机上传到 AWS

  4. Create and run a Python 3.9 Lambda to test things out: (Make sure you configure it to use the Layer you created in the previous step)创建并运行 Python 3.9 Lambda 以进行测试:(确保将其配置为使用您在上一步中创建的层)

     import pyodbc def lambda_handler(event, context): driver = '{ODBC Driver 17 for SQL Server}' server = 'XXX' port = '1433' database = 'XXX' username = 'XXX' password = 'XXX' # ideally put this in a SecretsManager secret instead of directly in the code connection = pyodbc.connect(f'DRIVER={driver};SERVER={server},{port};DATABASE={database};UID={username};PWD={password}') cursor = connection.cursor() query = """ select @@version """ cursor.execute(query) for row in cursor.fetchall(): print(row[0])

I think your problem is uploading the layer without the appropriate folder structure specified in the documentation我认为您的问题是在没有在文档中指定的适当文件夹结构的情况下上传图层

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

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