AWS 如何在lambda函数中使用Python依赖库pymssql
作者: Jim Wang 公众号: 巴博萨船长
任务背景
任务为使用aws的lambda函数从一个MS SQL数据库中读取部分的数据,然后对数据处理后,转存至aws的DyanmoDB上,因为需要从MS SQL数据库中读取信息,代码就需要相关依赖,Python对MS SQL的依赖库为pymssql,初步计划lambda 的函数使用Python来完成,版本为Python 3.6。本文主要介绍,如何在aws lambda函数中使用python依赖库pymssql。
所遇问题
aws lambda 的 Python 3.6 的运行环境,是不具有pymssql这个依赖包的,该依赖包并非标准库,又PyPI(Python Package Index)是python官方的第三方库的仓库管理维护,可以通过pip命令获取和安装。aws lambda 函数Python Runtime 运行时与操作系统如下,总的来说lambda函数是运行在Amazon Linux的操作系统上的,Amazon Linux和Amazon Linux2的区别就是内核版本有区别。
Python 运行时 | |||
---|---|---|---|
名称 | 标识符 | 适用于 Python 的 AWS 开发工具包 | 操作系统 |
Python 3.8 | python3.8 |
boto3-1.14.17 botocore-1.17.17 | Amazon Linux 2 |
Python 3.7 | python3.7 |
boto3-1.14.17 botocore-1.17.17 | Amazon Linux |
Python 3.6 | python3.6 |
boto3-1.14.17 botocore-1.17.17 | Amazon Linux |
Python 2.7 | python2.7 |
boto3-1.14.17 botocore-1.17.17 | Amazon Linux |
在测试中,我们使用的lambda函数名为test,Python文件名为lambda_function.py,该文件内容为,lambda函数的范例代码,内容如下。其中第二行为修改内容,主要为了引入pymssql模块。
1 | import json |
由于pymssql不是标准库,所以如果直接在lambda函数中引用该包,则lambda的执行结果为:失败,错误信息为:
1 | { |
日志输出为,
1 | START RequestId: d77542a0-d9c0-426a-a050-04948dc8464a Version: $LATEST |
可以看出,程序错误的原因为无法引入pymssql这个模块,是一个依赖问题。基本的共识为:不同版本的Python的相同第三方依赖包的内容是不同的,同样的不同操作系统的相同第三方依赖包的内容也是不同的。所以在调试代码也好,解决依赖也好,就需要创建一个Python版本隔离并且依赖隔离的环境,这部分内容,在python相关的文章里都有介绍,若有需要可以查看相关文章。
解决方法
解决问题的思路有两种:第一种,使用lambda 层(Layer)的方式解决依赖问题,另一种为将依赖内容与lambda函数的py文件整合在一起解决依赖问题。lambda函数代码更新可以通过,网页端,上传zip程序包或Amazone S3中引用,三种方式完成,本文主要讨论的以zip压缩文件作为程序包来更新lambda的相关代码部分。
创建 lambda 程序的依赖项程序包
要创建一个运行在linux系统下,Python 3.6运行时的lambda函数相关依赖项的程序包,就要创建并启动一个Python的隔离运行环境。关于如何创建这样一个隔离环境,也请参考python相关文章。
启动虚拟环境
比如,在Linux系统下,我们有如下的一个名为env3612的python虚拟环境,则可以在终端里输入pyenv activate env3612命令来启动这个虚拟环境,
1 | username@mac:~# pyenv virtualenvs |
创建工作文件夹
在相关虚拟运行环境启动后,就可以创建一个工作目录,下面代码中第一层目录的文件夹pymssql-dependencies这个名字可以自定义,其不对后续操作产生影响,第二层目录的文件夹python,该文件夹名非常重要,请保持一致。
1 | username@mac:~# mkdir pymssql-dependencies |
安装单一Python库
进入最终工作目录python之后,即可使用pip命令pip install pymssql -t ./
,就可以单独安装pymssql这个依赖库安装到这个python文件夹内,安装之后,文件夹内仅有pymssql相关内容。
1 | (env3612) username@mac:~/pymssql-dependencies/python# pip install pymssql -t ./ |
压缩程序包
完成pymssql之后,需要从python这个文件夹返回至上一级目录,再使用zip -r ~/tmp/pymssql-dependencies.zip .
将python目录内的所有内容压缩成zip文件。该文件可以理解为lambda函数的程序包。
1 | (env3612) username@mac:~/pymssql-dependencies/python# cd .. |
一、通过 lambda 层解决依赖问题
该方法解决问题是,首先要创建一个lambda 函数的层,配置信息请参考下方图片。在这里层的名称可以自定义,因为其只做为索引,在lambda函数引入层时,被用于索引。与之后要上传至层的zip文件名,和zip文件内的文件都无关系。
创建lambda层
然后选择之前创建的zip文件,上传后点击创建
,就可以完成相关lambda层的创建。再在lambda函数的配置页面点击Layers
,然后选择添加层
,为test这个lambda函数的指定一个layer。
然后在如下页面选择自定义层
,选择层的名称,点击添加
即可完成配置。
然后就可以再次测试该lambda函数。这时候lambda的执行结果为:成功,详细信息为:
1 | { |
日志输出为,
1 | START RequestId: ee1f059b-8288-4463-8501-8f36df9a6d67 Version: $LATEST |
如上的信息表明,上述方法已经通过lambda函数的层的方式解决了依赖问题,通过该方法也可以解决其他相关依赖的相似问题。
二、通过 lambda 代码解决依赖问题
该方法前期准备工作与方法一相同,都需要创建Python的隔离运行环境,并安装pymssql至python文件夹内,在安装以后,python文件夹的具体情况如下,
1 | (env3612) username@mac:~/pymssql-dependencies/python# ls -al |
这时候需要将lambda函数的py文件,即lambda_function.py拷贝至该目录,然后在python目录下,运行zip -r ~/Downloads/test.zip .
命令,将python文件内的所有文件压缩成为一个名为test.zip的压缩文档,如下,
1 | (env3612) username@mac:~/pymssql-dependencies/python# zip -r ~/Downloads/test.zip . |
在这里,zip的文件名最好与lambda函数保持一致,文件名称字母大小写不敏感。然后点击lambda函数中函数代码
部分的操作
按钮,然后选择上传.zip文件
项,接着选择test.zip压缩文件,点击保存
即可。
完成上述内容,然后点击测试,就可以得到与方法一一样的成功执行结果。
小结
上述两个方法中,程序包的部署,可以通过网页端完成,也可以通过aws-cli来实现。zip的文件包也可以先上传至Amazone S3存储内,然后在页面端选择使用。在尝试两个方法的时候,要注意打包zip程序包时,命令行的当前目录,方法一需要在python上一级目录。方法二需要确保在python目录内。上述两个方案仅为一家之言,并非最优,若读者有别的思路也欢迎关注我的个人微信公众号,一起讨论学习。
文章首发于 Jim Wang's blog , 转载文章请务必以超链接形式标明文章出处,作者信息及本版权声明。