
本文讲解为何连续调用 put_item 会导致 DynamoDB 记录被覆盖,并提供使用 update_item 原子化追加字段的正确实践,附可运行 Python 示例与关键注意事项。
本文讲解为何连续调用 `put_item` 会导致 dynamodb 记录被覆盖,并提供使用 `update_item` 原子化追加字段的正确实践,附可运行 python 示例与关键注意事项。
在 DynamoDB 中,put_item 是全量写入操作:只要指定了主键(如 pk),它就会用传入的整个 Item 字典完全替换该主键下已存在的整条记录。你当前的代码在循环中对同一 pk='787' 连续执行两次 put_item:
# 第一次:写入 {"pk": "787", "orderId": "569782152"}
# 第二次:写入 {"pk": "787", "incBaseFx": "1.0"} → 覆盖前一条,仅剩后者
因此最终表中只保留最后一次写入的字段,造成“丢失”现象。
✅ 正确做法是:一次性构建完整属性字典,再单次调用 put_item;或更推荐——使用 update_item 原子化追加/更新字段,尤其适合动态、分步写入场景。
✅ 推荐方案一:单次 put_item(适用于已知全部字段)
record_data = "orderId:569782152,incBaseFx:1.0"
record_data_list = record_data.split(",")
# 构建完整 item 字典
item = {"pk": "787"}
for record_data_list_item in record_data_list:
x, y = record_data_list_item.split(":")
item[x] = y
table.put_item(Item=item) # 仅一次调用,写入完整记录
✅ 推荐方案二:使用 update_item(支持增量更新、条件写入、原子操作)
from boto3.dynamodb.types import STRING
record_data = "orderId:569782152,incBaseFx:1.0"
record_data_list = record_data.split(",")
# 构建 UpdateExpression 和 ExpressionAttributeNames/Values
update_expr_parts = []
expr_attr_names = {}
expr_attr_values = {}
for i, record_data_list_item in enumerate(record_data_list):
x, y = record_data_list_item.split(":")
placeholder = f"#k{i}"
value_placeholder = f":v{i}"
update_expr_parts.append(f"{placeholder} = {value_placeholder}")
expr_attr_names[placeholder] = x
expr_attr_values[value_placeholder] = y
update_expression = "SET " + ", ".join(update_expr_parts)
table.update_item(
Key={"pk": "787"},
UpdateExpression=update_expression,
ExpressionAttributeNames=expr_attr_names,
ExpressionAttributeValues=expr_attr_values,
ReturnValues="ALL_NEW" # 可选:返回更新后的完整项
)
⚠️ 关键注意事项:
- put_item 没有“合并”逻辑,永远是覆盖写入;
- update_item 支持 ADD, DELETE, SET, REMOVE 等操作,且天然支持嵌套属性(如 #user.#profile.#age);
- 若需确保字段不存在时才写入,可结合 ConditionExpression(例如 attribute_not_exists(orderId));
- 所有 update_item 操作在服务端是原子的,无需担心并发写入导致部分字段丢失;
- 字段名含特殊字符或保留字(如 order, type)时,必须通过 ExpressionAttributeNames 显式映射,避免语法错误。
掌握 put_item 与 update_item 的语义差异,是高效、安全使用 DynamoDB 的基础。优先选择 update_item 处理多字段动态写入,既简洁又健壮。










