You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DynamoDB主键不存在时插入数据、存在时不更新返回原数据的实现问题

解决方案

你需要的「主键不存在时创建条目、主键已存在时不更新直接返回原有数据」的逻辑,有两种成熟实现方式。你之前putItem报错的原因是:if_not_exists 函数仅允许在 UpdateExpression 中使用,不能用于 ConditionExpression,条件判断属性不存在直接用 attribute_not_exists() 函数即可。

方案1:修正putItem实现(适合全条目写入场景)

修改ConditionExpression为判断主键不存在,同时新增异常分支处理主键已存在的场景,捕获到ConditionalCheckFailedException时主动查询原有数据返回:

const str = randomize('Aa0', 6);

const params = {
  TableName: "alexa-connections-table",
  Item: {
    "alexaDeviceId": {
      S: process.env.TEST_ALEXA_DEVICE_ID
    },
    "connectionString": {
      S: str
    }
  },
  // 仅当主键不存在时才执行put操作
  ConditionExpression: 'attribute_not_exists(alexaDeviceId)'
};

try {
  await dynamodb.putItem(params).promise();
  // 写入成功直接返回新写入的数据
  const result = {
    Attributes: params.Item
  };
  console.log('Results: ' + JSON.stringify(result));
  return res.status(200).send(JSON.stringify(result));
} catch (err) {
  // 捕获条件校验失败的异常,说明主键已存在
  if (err.code === 'ConditionalCheckFailedException') {
    // 查询原有数据返回
    const getParams = {
      TableName: "alexa-connections-table",
      Key: {
        "alexaDeviceId": {
          S: process.env.TEST_ALEXA_DEVICE_ID
        }
      }
    };
    const existResult = await dynamodb.getItem(getParams).promise();
    return res.status(200).send(JSON.stringify({Attributes: existResult.Item}));
  }
  console.log(err);
  return res.status(500).send({ reason: err });
}

方案2:修正updateItem实现(更简洁,无需额外查询)

利用updateItem自带的「主键不存在自动创建」特性,结合if_not_exists函数实现仅属性不存在时赋值,无需额外异常处理和查询:

const str = randomize('Aa0', 6);

const params = {
  TableName: "alexa-connections-table",
  Key: {
    "alexaDeviceId": {
      S: process.env.TEST_ALEXA_DEVICE_ID
    }
  },
  ExpressionAttributeNames: {
    "#CS": "connectionString"
  },
  ExpressionAttributeValues: {
    ":connection": {
      S: str
    }
  },
  ReturnValues: "ALL_NEW",
  // 仅当connectionString不存在时才赋值
  UpdateExpression: "SET #CS = if_not_exists(#CS, :connection)"
};

try {
  const result = await dynamodb.updateItem(params).promise();
  console.log('Results: ' + JSON.stringify(result));
  return res.status(200).send(JSON.stringify(result));
} catch (err) {
  console.log(err);
  return res.status(500).send({ reason: err });
}

如果需要严格限制「只要主键存在就完全不执行任何写入操作」,可以在上述updateItem参数中额外添加ConditionExpression: 'attribute_not_exists(alexaDeviceId)',之后和方案1一样捕获ConditionalCheckFailedException异常查询旧数据返回即可。


内容的提问来源于stack exchange,提问作者WHOATEMYNOODLES

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:27:01