如何解决有条件地将项目放入DynamoDB
在我的Lambda函数中,仅当值尚未存在时,我才想有条件地将项目放入DynamoDB中。我看到多个不同的来源在他们使用此ConditionExpression的情况,但我无法弄清这是怎么回事。
body = await dynamo.put({
TableName: 'polit-stream',Item: {
urlPath: data.urlPath,},ConditionExpression: "attribute_not_exists(urlPath)"
}).promise();
即使我的二级索引值(urlPath)已经存在,放置也将始终成功。
完整代码:
const AWS = require('aws-sdk');
const crypto = require("crypto");
const dynamo = new AWS.DynamoDB.DocumentClient();
/**
* Demonstrates a simple HTTP endpoint using API Gateway. You have full
* access to the request and response payload,including headers and
* status code.
*
* To scan a DynamoDB table,make a GET request with the TableName as a
* query string parameter. To put,update,or delete an item,make a POST,* PUT,or DELETE request respectively,passing in the payload to the
* DynamoDB API as a JSON body.
*/
exports.handler = async(event,context) => {
let body;
let statusCode = '200';
const headers = {
'Content-Type': 'application/json','Access-Control-Allow-Origin': '* '
}
const data = JSON.parse(event.body);
const generateUUID = () => crypto.randomBytes(16).toString("hex");
try {
switch (event.httpMethod) {
case 'DELETE':
body = await dynamo.delete(JSON.parse(event.body)).promise();
break;
case 'GET':
body = await dynamo.scan({
TableName: 'db',IndexName: 'urlPath',FilterExpression: "urlPath = :urlPath",ExpressionAttributeValues: {
":urlPath": event.queryStringParameters.urlPath
}
},function(data) {
}).promise();
break;
case 'POST':
body = await dynamo.put({
TableName: 'db',Item: {
id: generateUUID(),name: data.name,date: data.date,place: data.place,goals: data.goals,type: data.type,org: data.org,email: data.email,urlPath: data.urlPath,createdAt: new Date().toISOString()
},ConditionExpression: "attribute_not_exists(urlPath)"
}).promise();
break;
case 'PUT':
body = await dynamo.update(JSON.parse(event.body)).promise();
break;
default:
throw new Error(`Unsupported method "${event.httpMethod}"`);
}
}
catch (err) {
statusCode = '400';
body = err.message;
}
finally {
body = JSON.stringify(body);
}
return {
statusCode,body,headers,};
};
解决方法
您的错误是您误解了ConditionExpression
可以做什么。您完整的PutItem
代码是:
body = await dynamo.put({
TableName: 'db',Item: {
id: generateUUID(),name: data.name,date: data.date,place: data.place,goals: data.goals,type: data.type,org: data.org,email: data.email,urlPath: data.urlPath,createdAt: new Date().toISOString()
},ConditionExpression: "attribute_not_exists(urlPath)"
}
您期望ConditionExpression: "attribute_not_exists(urlPath)"
做什么?
您显然认为它会检查是否存在具有该值urlPath
的任何项目。不幸的是,但这不是此表达式的作用。它的作用是查看一个特定项目-具有相同密钥的项目(我不知道您的密钥是id
?),然后检查该特定项目是否具有urlPath
属性(具有任何值)。
如果urlPath
是商品的钥匙,那么这项工作就如您希望的那样。如果urlPath
是唯一的(根据您要执行的操作,看起来确实是唯一的),那么它实际上可以用作项目密钥。
为了使用ConditionExpression,您需要提供属性的名称和值。试试这个:
await dynamo.put({
TableName: 'db',Item: {
id: generateUUID(),createdAt: new Date().toISOString(),},ConditionExpression: "attribute_not_exists(#u) or (#u=:urlPath)",ExpressionAttributeNames: { "#u": "urlPath" },ExpressionAttributeValues: { ":urlPath": data.urlPath },});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。