AWS IoT TwinMaker自定义数据源DataReader报错求助(Node.js 22兼容)
修复AWS IoT TwinMaker自定义DataReader在Node.js 22的兼容性问题
问题根源分析
你的代码存在以下几个核心问题,导致在Node.js 22环境下运行出错:
- 新旧AWS SDK混用:同时引入了AWS SDK v2和v3,Node.js 22对v2兼容性较差,且v3客户端不支持
.promise()调用 - 变量类型错误:
res被初始化为数组,却用属性名作为键存储数据,逻辑矛盾 - 未处理DynamoDB原生数据类型:直接读取
item[prop]会拿到DynamoDB的类型对象(如{ N: "123" }),无法直接作为数值返回给TwinMaker
修复后的完整代码
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb"; const TABLE = 'TwinMakerTable'; const dynamo = new DynamoDBClient({}); // 解析DynamoDB原生数据类型为普通JS类型 const parseDynamoValue = (value) => { if (value.N) return parseFloat(value.N); if (value.S) return value.S; if (value.BOOL) return value.BOOL; return null; }; export const handler = async (event) => { try { const { workspaceId, entityId, componentName, selectedProperties, startTime, endTime } = event; // 构建DynamoDB查询命令(SDK v3命令模式) const command = new QueryCommand({ TableName: TABLE, ProjectionExpression: `${selectedProperties.join(', ')}, #tmsp`, KeyConditionExpression: `thingName = :hashKey AND #tmsp BETWEEN :startTime AND :endTime`, ExpressionAttributeNames: { '#tmsp': 'timestamp' }, ExpressionAttributeValues: { ':hashKey': { S: entityId }, ':startTime': { N: (new Date(startTime)).getTime().toString() }, ':endTime': { N: (new Date(endTime)).getTime().toString() } } }); // 执行查询(SDK v3使用send方法替代promise()) const response = await dynamo.send(command); const { Items } = response; const results = { propertyValues: [] }; // 修正为对象存储属性数据 const res = {}; Items.forEach(item => { selectedProperties.forEach(prop => { if (!res[prop]) { res[prop] = { entityPropertyReference: { propertyName: prop, componentName, entityId: event.entityId }, values: [] }; } // 解析DynamoDB数据类型后添加到结果 res[prop].values.push({ time: (new Date(parseDynamoValue(item['timestamp']))).toISOString(), value: { doubleValue: parseDynamoValue(item[prop]) } }); }); }); for (let key in res) { results.propertyValues.push(res[key]); } console.log(results); return results; } catch (e) { console.error('DataReader执行错误:', e); // 抛出错误让TwinMaker捕获,避免静默失败 throw e; } };
关键修改说明
- 完全迁移到AWS SDK v3:移除v2的
AWS.DynamoDB导入,使用v3的DynamoDBClient和QueryCommand,符合Node.js 20+版本的最佳实践 - 替换异步调用方式:用
send(command)替代v2的.promise(),适配v3的命令式API - 修正数据类型处理:添加
parseDynamoValue函数,将DynamoDB的类型对象转换为普通JavaScript类型 - 修复存储结构:把
res从数组改为对象,正确存储每个属性对应的时间序列数据 - 显式类型赋值:在
ExpressionAttributeValues中明确指定DynamoDB数据类型(如{ S: entityId }),避免隐式转换错误
内容的提问来源于stack exchange,提问作者ash bash
相关产品推荐
相关产品推荐

