如何将自定义包中的模块正确导入AWS Lambda函数?

2024-05-04 13:51:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我是AWS的新手,需要一些建议。我有一个有几个AWS Lambda函数的项目。在我的例子中,有四个,它们位于functions文件夹中。它们都需要使用数据库连接。因此,我决定将与数据库相关的代码放在一个名为databases的单独包中,并在AWS Lambda层中使用它。如您所见,databases包有两个模块。从文档中我了解到,我需要归档我的包并将其放入AWS Lambda层中。但是,此包的地址会发生更改。因为AWS默认情况下将其放在/opt目录中。我有点困惑。如何正确地将自定义软件包中的模块导入AWS Lambda函数,使其在本地和生产中工作

我的项目的结构如下所示:

src
   functions
      create_user_information
         __init__.py
         lambda_function.py
      update_user_information
         __init__.py
         lambda_function.py
      get_user_information
         __init__.py
         lambda_function.py
      delete_user_information
         __init__.py
         lambda_function.py
   layers
      databases
         __init__.py
         cassandra.py
         postgresql.py
         requirements.txt
template.yaml
venv
   bin
      ...
   include
   lib
      ...

lambda_函数.py:

from src.layers.databases import cassandra


cassandra_db_session = None
cassandra_db_username = 'your-username'
cassandra_db_password = 'your-password'
cassandra_db_endpoints = ['your-endpoint']
cassandra_db_port = 9142


def lambda_handler(event, context):
    global cassandra_db_session
    if not cassandra_db_session:
        cassandra_db_session = cassandra.create_session(
            cassandra_db_username,
            cassandra_db_password,
            cassandra_db_endpoints,
            cassandra_db_port
        )
    # Some business logic.
    # ...
    return "AWS Lambda function finished."

模板。yaml:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: User Information Service
Globals:
    Function:
        Timeout: 10
Resources:
    Databases:
        Type: AWS::Serverless::LayerVersion
        Properties:
            LayerName: Databases
            Description:
            ContentUri:
            CompatibleRuntimes:
                - python3.8
            LicenseInfo: MIT
            RetentionPolicy: Retain
    GetUserInformation:
        Type: AWS::Serverless::Function
        Properties:
            FunctionName: GetUserInformation
            Description:
            CodeUri: src/functions/get_user_information
            Handler: lambda_function.lambda_handler
            Runtime: python3.8
            Layers:
                - !Ref Databases
    CreateUserInformation:
        Type: AWS::Serverless::Function
        Properties:
            FunctionName: CreateUserInformation
            Description:
            CodeUri: src/functions/create_user_information
            Handler: lambda_function.lambda_handler
            Runtime: python3.8
            Layers:
                - !Ref Databases
    UpdateUserInformation:
        Type: AWS::Serverless::Function
        Properties:
            FunctionName: UpdateUserInformation
            Description:
            CodeUri: src/functions/update_user_information
            Handler: lambda_function.lambda_handler
            Runtime: python3.8
            Layers:
                - !Ref Databases
    DeleteUserInformation:
        Type: AWS::Serverless::Function
        Properties:
            FunctionName: DeleteUserInformation
            Description:
            CodeUri: src/functions/delete_user_information
            Handler: lambda_function.lambda_handler
            Runtime: python3.8
            Layers:
                - !Ref Databases
Outputs:
    DatabasesARN:
        Value: !Ref Databases
        Description: Databases ARN
        Export:
            Name: databases-arn

Tags: lambdapysrcawsdbinformationinitfunction
1条回答
网友
1楼 · 发布于 2024-05-04 13:51:00

假设您已经打包了databases并在层中正确安装了它,那么您的导入将非常简单:

# assume 'databases' is the installation name of your pkg
from databases import cassandra  
  1. 您的包必须是“可安装”的,上面的代码才能工作,但它看不到这一点。网上有很多关于如何正确操作的参考资料

重要的是要注意,你不需要遵循这种方法(除了被推荐之外)。您可以将整个src文件夹打包并作为lambda函数上载,因此您可以按如下方式使用:

# don't use relative imports in lambda because the change to opt/
from src.layers.databases import cassandra  

当前的问题不是由任何类型的“目录更改”引起的,而是由不正确的包装引起的

相关问题 更多 >