DynamoDB调用putItem写入user_id时类型不匹配报错如何解决
问题根因
两个报错不存在校验逻辑矛盾,核心是两点认知偏差加一处代码bug:
- 你的
user_data表中,user_id作为分区键的定义类型是S(字符串),而非数字类型N - 你使用AWS DynamoDB低级SDK时,给
user_id错误标注了"N"类型,相当于告诉SDK“该字段值为数字”:- 传包含字母的随机ID时,SDK尝试将带字母的字符串转换为数值失败,抛出
ValidationException: The parameter cannot be converted to a numeric value错误 - 传纯数字格式字符串
"999999"时,SDK成功将其识别为数字类型N提交给服务端,服务端校验表结构发现主键期望类型为S,实际传值为N,抛出ValidationException: Type mismatch for key user_id expected: S actual: N错误
- 传包含字母的随机ID时,SDK尝试将带字母的字符串转换为数值失败,抛出
- 额外代码bug:写入成功的回调中直接引用了未定义的
user_id变量,就算类型校验通过也会触发引用错误。
不建议修改表结构把
user_id改成N类型适配错误代码:你的随机ID长度为30位,远超JavaScript的安全整数上限(2^53-1,约16位十进制数),后续查询、处理时很容易出现精度丢失,用字符串类型存主键ID是通用最佳实践。
修复方案
- 将
user_id字段的类型标记从"N"改为"S",和表定义的主键类型保持一致,直接传入随机ID生成器返回的字符串即可 - 提前将生成的用户ID存入变量,修复回调中的未定义变量引用问题
修复后完整代码
const AWS = require('aws-sdk'); const dynamo = new AWS.DynamoDB(); // 原有随机ID生成器逻辑无需修改 function r() { //生成30位长度随机字符串 let res = ''; const chars = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9"]; for (let i = 0; i < 30; i++) { res += chars[Math.floor(Math.random() * chars.length)]; } return res; } async function addUser(username, password, email, firstName) { // 提前生成用户ID存入作用域变量 const userId = r(); const items = { "user_id": { // 类型标记修正为S,传入生成的字符串ID "S": userId }, "username": { "S": username }, "password": { "S": password }, "email": { "S": email }, "firstName": { "S": firstName } }; return new Promise((res, rej) => { dynamo.putItem({ TableName: 'user_data', Item: items }, (err, data) => { if (err) rej(err); // 引用提前定义的userId变量,避免未定义错误 else res({ id: userId, message: `User added to database with user_id ${userId}` }); }); }); } // 调用示例 addUser("test", "test", "test", "test") .then(result => console.log(result)) .catch(err => console.error(err));
表字段配置参考

内容的提问来源于stack exchange,提问作者stonefish
相关产品推荐
相关产品推荐

