使用 AWS Lambda 将记录推送到 AWS DynamoDB
Pushing records to AWS DynamoDB with AWS Lambda
我正在尝试将记录从 AWS Lambda 函数推送到 AWS DynamoDB。我可以使用 AWS API 从我的电脑成功推送一条记录,但是当我将代码部署到 AWS 时,我被卡住了。
下面是可以成功从我的 PC 推送记录的示例代码:
const AWS = require("aws-sdk");
AWS.config.update({
region: "eu-west-1",
endpoint: "https://dynamodb.eu-west-1.amazonaws.com"
});
const docClient = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: "hello-world-bot",
Item: {
timestamp: Date.now(),
chat_id: 123,
text: 'text',
},
};
console.log("Adding a new item...");
docClient.put(params, function(err, data) {
if (err) {
console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Added item:", JSON.stringify(data, null, 2));
}
});
DynamoDB 中的结果:
Screenshot from DynamoDB console
这是我要部署到 Lambda 的代码:
const AWS = require("aws-sdk");
AWS.config.update({
region: "eu-west-1",
endpoint: "https://dynamodb.eu-west-1.amazonaws.com",
});
const docClient = new AWS.DynamoDB.DocumentClient();
module.exports.helloworld = (event) => {
const params = {
TableName: "hello-world-bot",
Item: {
timestamp: Date.now(),
chat_id: 123,
text: "text",
},
};
console.log("Adding a new item...");
docClient.put(params, function (err, data) {
if (err) {
console.error(
"Unable to add item. Error JSON:",
JSON.stringify(err, null, 2)
);
} else {
console.log("Added item:", JSON.stringify(data, null, 2));
}
});
return { statusCode: 200 };
};
而且麻烦的是,当Lambda函数运行s时,DynamoDB中没有任何记录。
以下是当我拉取 Lambda 外部 API 并尝试 运行 函数时来自 CloudWatch 的日志:
START RequestId: d9e171c2-a763-4df1-9ec3-06d79eb68a1e Version: $LATEST
2021-08-13T06:03:01.974Z d9e171c2-a763-4df1-9ec3-06d79eb68a1e INFO Adding a new item...
END RequestId: d9e171c2-a763-4df1-9ec3-06d79eb68a1e
REPORT RequestId: d9e171c2-a763-4df1-9ec3-06d79eb68a1e Duration: 45.04 ms Billed Duration: 46 ms Memory Size: 1024 MB Max Memory Used: 88 MB Init Duration: 524.54 ms
如您所见,没有任何关于权限或其他方面的错误。
这些是其凭据在 Lambda 中与此函数一起使用的用户权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchWriteItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:eu-west-1:120400915578:table/hello-world-bot"
}
]
}
您的 return { statusCode: 200 };
结束了 lambda 调用,但它不会等待 put
请求完成。实际上,它可能甚至不等待它开始。
return 来自 put
回调的主函数,或者使用 promises。承诺示例:
module.exports.helloworld = async (event) => { // <- use async
const params = {
TableName: "hello-world-bot",
Item: {
timestamp: Date.now(),
chat_id: 123,
text: "text",
},
}
console.log("Adding a new item...")
// Create a promise and return it
return docClient
.put(params)
.promise()
.then(() => {
console.log("success")
return {statusCode: 200}
})
.catch(e => {
console.log("error: ", e)
return {statusCode: 500}
})
}
此外,正如@jens 在评论中指出的那样,不需要明确设置 dynamodb 端点
正如我在其他答案的评论中指出的那样,他们的 return 陈述似乎并不完全正确。我更愿意对 lambda 和开箱即用的 AWS SDK 支持的承诺使用异步等待语法。
这会将您的代码更改为如下所示:
const AWS = require("aws-sdk");
const docClient = new AWS.DynamoDB.DocumentClient();
module.exports.helloworld = async (event) => {
const params = {
TableName: "hello-world-bot",
Item: {
timestamp: Date.now(),
chat_id: 123,
text: "text",
},
};
console.log("Adding a new item...");
try {
await docClient.put(params).promise();
return { statusCode: 200 };
} catch (err) {
console.error("Unable to add item. Error JSON:",
JSON.stringify(err, null, 2));
return { statusCode: 500 };
}
};
PS:正如评论中所指出的,如果您使用的是默认端点,则无需为 DynamoDB 设置端点。因为你是 运行 作为 Lambda 的函数,AWS_REGION
环境变量将自动设置,所以你也不需要自己配置它(除非你想访问 DynamoDB table在另一个地区)。
我正在尝试将记录从 AWS Lambda 函数推送到 AWS DynamoDB。我可以使用 AWS API 从我的电脑成功推送一条记录,但是当我将代码部署到 AWS 时,我被卡住了。
下面是可以成功从我的 PC 推送记录的示例代码:
const AWS = require("aws-sdk");
AWS.config.update({
region: "eu-west-1",
endpoint: "https://dynamodb.eu-west-1.amazonaws.com"
});
const docClient = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: "hello-world-bot",
Item: {
timestamp: Date.now(),
chat_id: 123,
text: 'text',
},
};
console.log("Adding a new item...");
docClient.put(params, function(err, data) {
if (err) {
console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Added item:", JSON.stringify(data, null, 2));
}
});
DynamoDB 中的结果: Screenshot from DynamoDB console
这是我要部署到 Lambda 的代码:
const AWS = require("aws-sdk");
AWS.config.update({
region: "eu-west-1",
endpoint: "https://dynamodb.eu-west-1.amazonaws.com",
});
const docClient = new AWS.DynamoDB.DocumentClient();
module.exports.helloworld = (event) => {
const params = {
TableName: "hello-world-bot",
Item: {
timestamp: Date.now(),
chat_id: 123,
text: "text",
},
};
console.log("Adding a new item...");
docClient.put(params, function (err, data) {
if (err) {
console.error(
"Unable to add item. Error JSON:",
JSON.stringify(err, null, 2)
);
} else {
console.log("Added item:", JSON.stringify(data, null, 2));
}
});
return { statusCode: 200 };
};
而且麻烦的是,当Lambda函数运行s时,DynamoDB中没有任何记录。 以下是当我拉取 Lambda 外部 API 并尝试 运行 函数时来自 CloudWatch 的日志:
START RequestId: d9e171c2-a763-4df1-9ec3-06d79eb68a1e Version: $LATEST
2021-08-13T06:03:01.974Z d9e171c2-a763-4df1-9ec3-06d79eb68a1e INFO Adding a new item...
END RequestId: d9e171c2-a763-4df1-9ec3-06d79eb68a1e
REPORT RequestId: d9e171c2-a763-4df1-9ec3-06d79eb68a1e Duration: 45.04 ms Billed Duration: 46 ms Memory Size: 1024 MB Max Memory Used: 88 MB Init Duration: 524.54 ms
如您所见,没有任何关于权限或其他方面的错误。 这些是其凭据在 Lambda 中与此函数一起使用的用户权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchWriteItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:eu-west-1:120400915578:table/hello-world-bot"
}
]
}
您的 return { statusCode: 200 };
结束了 lambda 调用,但它不会等待 put
请求完成。实际上,它可能甚至不等待它开始。
return 来自 put
回调的主函数,或者使用 promises。承诺示例:
module.exports.helloworld = async (event) => { // <- use async
const params = {
TableName: "hello-world-bot",
Item: {
timestamp: Date.now(),
chat_id: 123,
text: "text",
},
}
console.log("Adding a new item...")
// Create a promise and return it
return docClient
.put(params)
.promise()
.then(() => {
console.log("success")
return {statusCode: 200}
})
.catch(e => {
console.log("error: ", e)
return {statusCode: 500}
})
}
此外,正如@jens 在评论中指出的那样,不需要明确设置 dynamodb 端点
正如我在其他答案的评论中指出的那样,他们的 return 陈述似乎并不完全正确。我更愿意对 lambda 和开箱即用的 AWS SDK 支持的承诺使用异步等待语法。
这会将您的代码更改为如下所示:
const AWS = require("aws-sdk");
const docClient = new AWS.DynamoDB.DocumentClient();
module.exports.helloworld = async (event) => {
const params = {
TableName: "hello-world-bot",
Item: {
timestamp: Date.now(),
chat_id: 123,
text: "text",
},
};
console.log("Adding a new item...");
try {
await docClient.put(params).promise();
return { statusCode: 200 };
} catch (err) {
console.error("Unable to add item. Error JSON:",
JSON.stringify(err, null, 2));
return { statusCode: 500 };
}
};
PS:正如评论中所指出的,如果您使用的是默认端点,则无需为 DynamoDB 设置端点。因为你是 运行 作为 Lambda 的函数,AWS_REGION
环境变量将自动设置,所以你也不需要自己配置它(除非你想访问 DynamoDB table在另一个地区)。