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

从Aurora只读副本同步数据到DynamoDB时遇JSON循环结构转换错误

问题分析与解决方案

看起来你遇到了两个关键问题:一个是读取数据属性时的Cannot read property 'id' of undefined错误,另一个是JSON序列化时的循环结构错误。咱们一步步来解决:

1. 数据属性读取错误的原因与修复

你从Aurora拿到的结果是一个数组([ { "id": 2, "name": "Display", "result": "Pass" } ]),但代码里你把它包裹成了var data = {results};,也就是data是一个包含results数组的对象。这时候直接访问data.id肯定是undefined,因为id属性在data.results[0]里面。

修复方式:直接从results数组的第一个元素中提取属性:

// 原错误代码
var params = {
  Item:{
    test_id:data.id,
    name:data.name,
    result:data.result
  },
  TableName: 'demo_rds_dynamoDB'
};

// 修复后
const record = results[0]; // 取数组里的第一条记录
var params = {
  Item:{
    test_id: record.id,
    name: record.name,
    result: record.result
  },
  TableName: 'demo_rds_dynamoDB'
};

2. 循环结构JSON序列化错误的原因与修复

这个错误是因为你在connection.end的回调里,把client.put()的返回值直接传给了callback:

connection.end(function (err) {
  callback(err, client.put(params, function(error,data){
    // ...
  }) );
});

client.put()返回的是AWS的请求对象,里面包含循环引用的结构(比如客户端实例的引用),当Lambda尝试把这个对象序列化为JSON返回时就会报错。而且这里的异步流程也有问题:client.put是异步操作,你应该在它的回调里才调用Lambda的callback,而不是把put的返回值传给callback。

修复后的异步流程应该是:

  • 先执行DynamoDB的put操作
  • 在put操作完成的回调里,关闭数据库连接
  • 最后调用Lambda的callback返回结果或错误

完整修复后的代码

把所有问题修复后,完整代码如下:

var AWS = require("aws-sdk");
var mysql = require('mysql');
const client = new AWS.DynamoDB.DocumentClient({region : 'eu-west-1'});

var connection = mysql.createPool({
  host : "**********",
  user : "****",
  password : "*****",
  database : "mydb",
  port : "3306"
});

exports.handler = (event, context, callback) => {
  connection.query('select * from demo where id=2;', function (error, results, fields) {
    if (error) {
      connection.end();
      return callback(error, null);
    }

    // 确保查询到了数据再继续,避免空数组报错
    if (!results || results.length === 0) {
      connection.end();
      return callback(new Error("No record found with id=2"), null);
    }

    const record = results[0];
    var params = {
      Item:{
        test_id: record.id,
        name: record.name,
        result: record.result
      },
      TableName: 'demo_rds_dynamoDB'
    };

    client.put(params, function(putError, putData){
      connection.end();
      if(putError){
        return callback(putError, null);
      }
      callback(null, putData);
    });
  });
};

额外优化建议

  • 不要在Lambda里直接throw error,应该用callback返回错误,否则会导致Lambda执行异常。
  • 增加查询结果的空值判断,避免当没有查询到数据时访问results[0]出现新的错误。
  • 考虑使用async/await来替代嵌套回调,让代码更易读(如果你的Node.js版本支持的话)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:33:52