在Python中使用MySQL和AWS Lambda的问题

时间:2016-03-03 04:44:52

标签: python mysql python-2.7 amazon-web-services aws-lambda

我正在尝试使用AWS Lambda Python(Python btw中的初学者)启动并运行,但在包含MySQL依赖项方面存在一些问题。我正在尝试按照Mac上的说明here进行操作。

对于第3步,我在项目的根目录下执行命令会遇到一些问题

sudo pip install MySQL-python -t /

错误:

  

例外:   Traceback(最近一次调用最后一次):     文件“/Library/Python/2.7/site-packages/pip-1.5.6-py2.7.egg/pip/basecommand.py”,第122行,主要       status = self.run(options,args)     文件“/Library/Python/2.7/site-packages/pip-1.5.6-py2.7.egg/pip/commands/install.py”,第311行,在运行中       os.path.join(options.target_dir,item)     文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py”,第292行,移动       raise Error,“目标路径'%s'已经存在”%real_dst   错误:目标路径'/MySQL_python-1.2.5-py2.7.egg-info/MySQL_python-1.2.5-py2.7.egg-info'已存在

我最终编写了以下lambda函数(在我的Mac上运行正常),即:

import MySQLdb

def lambda_handler(event, context):
   # Open database connection
   db = MySQLdb.connect(...)

   # prepare a cursor object using cursor() method
   cursor = db.cursor()

   sql = "SELECT * FROM Users"

   try:
      # Execute the SQL command
      cursor.execute(sql)
      # Fetch all the rows in a list of lists.
      results = cursor.fetchall()
      for row in results:
         fname = row[0]
         lname = row[1]
         age = row[2]
         sex = row[3]
         income = row[4]
         # Now print fetched result
         print ("lname=%s" %(lname))
   except:
      print "Error: unable to fecth data"

   # disconnect from server
   db.close()

我接下来要去/Library/Python/2.7/site-packages并复制我在做sudo pip时下载的MySQLdb文件夹/文件安装MySQL-python(不带-t /)(我确定我在这里做错了什么,对我的lambda项目,然后将内容与lambda_function.py一起压缩并上传到AWS Lambda。

然后我得到:

  

无法导入模块'lambda_function':没有名为MySQLdb的模块

感谢任何帮助和建议!

修改

能够做sudo pip安装MySQL-python -t / pathToProject工作(感谢评论中的帮助)但是现在我在运行lambda函数时得到了这个:

  

无法导入模块'lambda_function':/ var / task / _mysql.so:无效的ELF标题

我知道如果我在Linux机器上工作,那么它应该可以正常工作(正如一些人所建议的那样),但我想知道我是否可以从OS X机箱开始工作。

9 个答案:

答案 0 :(得分:9)

对于像Lambda这样的用例,使用像PyMySQL这样的纯python实现会更快乐。

Python Database API规范之后,它取代了MySQLdb。对于大多数事情,例如触发的Lambda事件,它将同样快。

我在制作中经常使用它并且效果很好。

答案 1 :(得分:3)

TLDR:是的,您可以在AWS Lambda Python函数中使用mysqlclient

这是一种方法-通过为mysqlclient(即MySQLdb)创建自己的AWS Lambda层。

然后我得到Unable to import module 'lambda_function': No module named MySQLdb

我知道,如果我在Linux机器上工作,那么它应该可以正常工作(有人建议),但是我想知道是否可以在OS X机器上使它工作。

在尝试使用AWS Lambda Python函数进行import MySQLdb时,我也面临着完全相同的错误。

经过大量搜索解决方案并且对使用pymysql作为替代品(出于性能和兼容性的原因)不满意之后,我最终为mysqlclient构建了自己的AWS Lambda Layer。我找不到mysqlclient的“现成”层-即使是很棒的KLayers project也没有。我很高兴与GitHub存储库共享一个示例“现成”层以及一个简单的解决方案,该解决方案使用AWS建议的过程为您的需求构建自己的自定义层。

mysqlclient(MySQLdb)是围绕MySQL API的高性能C实现的Python包装器。在大多数情况下,这通常比pymysql之类的纯python实现要快得多(有关示例,请参见this list),但同时也带来了一些问题,例如您面临的问题。

由于它是根据mysql-devel包(例如MySQL提供的.rpm.deb文件)编译的,因此mysqlclient链接到特定于平台的二进制文件,例如libmysqlclient.so为了工作。换句话说,来自Mac OS笔记本电脑的libmysqlclient.so(例如)在使用本文Amazon Linux 2形式的AWS Lambda环境中将无法使用。您需要在libmysqlclient.so中进行编译并使其在AWS Lambda环境中(或尽可能接近)编译,以使其在您的AWS Lambda函数中起作用。

Docker images from lambci的形式提供了紧密模拟的AWS-Lambda环境。

因此,要打包与AWS-Lambda兼容的mysqlclient,您可以:

  • 拉出合适的docker容器,例如lambci/lambda:build-python3.8
  • 导入MySQL repo GPG key
  • 安装MySQL repo setup RPM,以便yum可以找到并下载其他MySQL回购软件包
  • yum install必要的依赖项,例如适合您的用例的mysql-devel rpm
  • 在容器中运行pip install mysqlclient
  • 压缩必要的libmysqlclient.so文件和mysqlclient的python lib目录

这几乎是AWS官方推荐的过程:请参见How do I create a Lambda layer using a simulated Lambda environment with Docker?

这样创建的zip可用于为mysqlclient创建一个新的AWS Lambda层。您可以使用此层轻松使用mysqlclient,而Lambda函数中不会出现任何错误。

经过一番梳理,我终于有了完整的过程,并将其自动化为this GitHub project中的单个脚本(build.sh)。该代码构建了一个layer.zip文件,您可以将其直接上载为新的AWS Lambda层。该项目当前针对Python3.8和MySQL服务器8.0.x构建,但可以使用提供的说明和工具轻松地适应不同的Python版本和目标MySQL版本。回购中还有一个现成的layer.zip-如果您想针对MySQL v8.0.x和AWS Lambda函数中的Python 3.8使用mysqlclient,则可以使用import MySQLdb。我们的生产环境使用SqlAlchemy,它使用MySqlClient Lambda层,对我们来说一直很好。

将Lambda函数配置为使用如上所述构建的层(例如,使用上述仓库中的工具)后,您可以像平常一样在import MySQLdb def lambda_handler(event, context): return { 'statusCode': 200, 'body': 'MySQLdb was successfully imported' } 中使用Lambda函数并继续编写真实代码:

Time Color Food label
2020 red  Apple A
2019 red Orange A,B
2018 blue Apple A,B
2017 blue  Orange B  

希望这会有所帮助。

答案 2 :(得分:0)

您必须使用Amazon Linux实例来构建您的python包,然后将它们包含在您的Lambda部署包中。查看this excellent article有关如何操作的信息。文章中提到的软件包与您需要的软件包不同,但同样有助于我为我的lambdas构建psycopg2和pymssql。

答案 3 :(得分:0)

使用lambda-docker,您可以设置和测试Lambda函数,而无需访问类似的Linux环境。

要设置lambda,请使用lambda-docker构建映像运行分离的docker容器并在容器上运行pip install <package>命令。然后导出容器,获取usr/lib下的已安装软件包,并将它们放在AWS Lambda软件包中。

然后,您可以通过在lambda-docker映像上运行lambda来测试兼容性。如果可行,请前往并自信地上传到AWS Lambda。

docker run -d -v "$PWD":/var/task lambci/lambda:build-python2.7 tail -f /dev/null 

docker ps

docker exec 0c55aae443e6 pip install pandas

docker exec 0c55aae443e6 pip install sqlalchemy

docker exec 0c55aae443e6 pip freeze

docker exec 0c55aae443e6 python -c "import site; print(site.getsitepackages())"

docker container export -o lambda_ready_container 0c55aae443e6

答案 4 :(得分:0)

只需上传两个包来更新您的lambda层: -sqlalchemy -PyMySQL(用于代替mysqlclient的驱动程序)

现在将驱动程序URL更新为“ mysql + pymysql:// ...”。

这使您可以在现有环境中使用与Lambda环境兼容的pymysql驱动程序。

不要忘记为RDS设置VPC端点。这样可以确保性能和安全性。

答案 5 :(得分:0)

AWS最近针对Lambda中的数据库驱动程序和数据库访问问题提出了一个很好的解决方案:Aurora Data API。数据API使用AWS标准身份验证通过HTTP隧穿SQL。这样就避免了在Lambda中编译本机代码和使用传统数据库连接模型的问题。

我最终为其编写了一个与DB-API兼容的驱动程序:aurora-data-api(和一个SQLAlchemy dialect使用它):

import aurora_data_api

cluster_arn = "arn:aws:rds:us-east-1:123456789012:cluster:my-aurora-serverless-cluster"
secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:MY_DB_CREDENTIALS"
with aurora_data_api.connect(aurora_cluster_arn=cluster_arn, secret_arn=secret_arn, database="my_db") as conn:
    with conn.cursor() as cursor:
        cursor.execute("select * from pg_catalog.pg_tables")
        print(cursor.fetchall())

答案 6 :(得分:0)

Lambda->图层(添加新图层)

https://pypi.org/project/PyMySQL/#files下载pymysql的zip

下载时,解压缩,然后将父文件夹重命名为“ python”,然后重新压缩(应为python / {其中pysqlfile是}

在Lambda中添加一个名为“ pymysql”的层并上传该zip

然后在Lambda函数中导入pymysql

答案 7 :(得分:-1)

我认为您的问题主要归咎于缺少开发包。我想你需要以下内容:

sudo yum -y install mysql-devel

答案 8 :(得分:-3)

问题在我的Ubuntu安装程序中同样发生,真正的问题是因为它在mysql客户端连接器驱动程序上处于未决状态。因此解决方案是安装Mysql client-dev包以使MySQL-python开心(利用客户端库)。

# Ubuntu only(or setup vm for ubuntu inside your mac) 
# Three dependencies for MySQL python recompilation 
sudo apt-get install python-dev  libssl-dev

#Now the mysql client-dev  
sudo apt-get install libmysqlclient-dev

# If you like mariadb client
sudo apt-get install libmariadbclient-dev

对于MAC

# try this first
fink install mysql-unified-dev

# or this if above fail. 
brew install mysql
# you must add this to your user profile startup if you use brew 
export PATH=$PATH:/usr/local/mysql/bin

您可以在此处获得类似的答案:Mac OS X - EnvironmentError: mysql_config not found

然后尝试pip安装。

我不建议任何人使用“sudo pip”。你应该为你的python开发设置Virtualenv和virtualwrapper,它允许你在没有sudo的情况下进行pip。并且更容易隔离和测试新部署。 (虽然它没有解决mysqlclient-dev库问题)