我试图通过触发Python lambda表达式以编程方式将数据放入本地运行的DynamoDB容器中。
我正在尝试遵循此处提供的模板:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.Python.03.html 我正在使用amazon / dynamodb-local,您可以在此处下载:https://hub.docker.com/r/amazon/dynamodb-local
使用Ubuntu 18.04.2 LTS运行容器和Lambda服务器 AWS Sam CLI运行我的Lambda API Docker版本18.09.4 Python 3.6(您可以在下面的sam日志中看到它) python lambda的启动命令只是“ sam local start-api”
首先是我的Lambda代码
import json
import boto3
def lambda_handler(event, context):
print("before grabbing dynamodb")
# dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000",region_name='us-west-2',AWS_ACCESS_KEY_ID='RANDOM',AWS_SECRET_ACCESS_KEY='RANDOM')
dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")
table = dynamodb.Table('ContactRequests')
try:
response = table.put_item(
Item={
'id': "1234",
'name': "test user",
'email': "testEmail@gmail.com"
}
)
print("response: " + str(response))
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world"
}),
}
我知道我应该在localhost:8000拥有此表ContactRequests,因为我可以运行此脚本来查看我的docker容器dynamodb表 我已经在boto.resource调用中对各种值进行了测试,以包括访问密钥,区域名称和秘密密钥,但结果没有改善
dev@ubuntu:~/Projects$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
"TableNames": [
"ContactRequests"
]
}
我还能够成功打入dynamodb提供的localhost:8000 / shell
不幸的是,在运行时,如果我撞到了触发该方法的端点,则会收到一个类似这样的超时记录
Fetching lambci/lambda:python3.6 Docker container image......
2019-04-09 15:52:08 Mounting /home/dev/Projects/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro inside runtime container
2019-04-09 15:52:12 Function 'HelloWorldFunction' timed out after 3 seconds
2019-04-09 15:52:13 Function returned an invalid response (must include one of: body, headers or statusCode in the response object). Response received:
2019-04-09 15:52:13 127.0.0.1 - - [09/Apr/2019 15:52:13] "GET /hello HTTP/1.1" 502 -
请注意,没有触发任何打印方法,如果我删除对table.put的调用,则将成功调用打印方法。
我在Stack Overflow上看到了类似的问题,例如lambda python dynamodb write gets timeout error,它指出问题是我正在使用本地数据库,但我是否仍不能使用boto3写入本地数据库,如果我将其指向本地运行的dynamodb实例?
答案 0 :(得分:1)
您的运行Lambda函数的Docker容器无法通过127.0.0.1
到达DynamoDB。尝试改用DynamoDB本地docker容器的名称作为端点的主机名:
dynamodb = boto3.resource('dynamodb', endpoint_url="http://<DynamoDB_LOCAL_NAME>:8000")
您可以使用docker ps
查找<DynamoDB_LOCAL_NAME>
或为其命名:
docker run --name dynamodb amazon/dynamodb-local
然后连接:
dynamodb = boto3.resource('dynamodb', endpoint_url="http://dynamodb:8000")
答案 1 :(得分:0)
在这里找到了解决问题的方法:connecting AWS SAM Local with dynamodb in docker 问题提问者指出,他在线上看到他可能需要使用以下命令连接到相同的docker网络:
docker network create lambda-local
因此创建了这个网络,然后更新了我的sam命令和docker命令以使用该网络,就像这样:
docker run --name dynamodb -p 8000:8000 --network=local-lambda amazon/dynamodb-local
sam local start-api --docker-network local-lambda
此后,我不再遇到超时问题。 我仍在努力确切地了解为什么这是问题所在
不过,公平起见,同样重要的是,我也使用dynamodb容器名称作为boto3资源调用的主机。 因此,最终,将上述解决方案与“ Reto Aebersold”提供的答案结合在一起,创建了最终解决方案
dynamodb = boto3.resource('dynamodb', endpoint_url="http://<DynamoDB_LOCAL_NAME>:8000")