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

DynamoDB中String Set反序列化失败:无法还原原始String Set的技术咨询

How to Properly Marshall and Unmarshall String Sets with DynamoDB's @aws-sdk/util-dynamodb?

The Problem

I'm trying to marshall and unmarshall a String Set for DynamoDB using the @aws-sdk/util-dynamodb package, but the unmarshalling step doesn't restore the original Set — instead it returns an empty object. Here's my code:

import {marshall, unmarshall} from '@aws-sdk/util-dynamodb';
test('Marshall and Unmarshall Test', () => {
  const raw = { 'anArray': new Set([ 'Apple', 'Mango' ]) };
  console.log(JSON.stringify(marshall(raw))); // {"anArray":{"SS":["Apple","Mango"]}}
  const marshalledResult = marshall(raw);
  console.log(JSON.stringify(unmarshall(marshalledResult))); // {"anArray":{}}
});

The marshalling output looks correct, but I can't get the original String Set back after unmarshalling. What's the right way to handle String Sets when retrieving them from DynamoDB?


The Fixes

First, Why This Happens

By default, the unmarshall function doesn't convert DynamoDB's SS (String Set) type back to a JavaScript Set object. In some older package versions, you might even get an empty object instead of the expected array (the standard default conversion for SS is a plain array). The core issue is that the SDK prioritizes standard JS types (arrays) over Sets for broader compatibility, so we need to add an extra step to get back our original Set.

1. Quick Manual Conversion

The simplest approach is to take the array returned by unmarshall and convert it to a Set explicitly:

import {marshall, unmarshall} from '@aws-sdk/util-dynamodb';
test('Marshall and Unmarshall Test', () => {
  const raw = { 'anArray': new Set([ 'Apple', 'Mango' ]) };
  const marshalledResult = marshall(raw);
  
  // Unmarshall to get an array, then convert to Set
  const unmarshalled = unmarshall(marshalledResult);
  const restoredData = {
    ...unmarshalled,
    anArray: new Set(unmarshalled.anArray)
  };
  
  console.log(restoredData); // { anArray: Set(2) { 'Apple', 'Mango' } }
});

2. Reusable Custom Unmarshaller

If you work with Sets often, create a helper function to automatically convert all DynamoDB set types back to JS Sets:

import {marshall, unmarshall} from '@aws-sdk/util-dynamodb';

function unmarshallWithSets(data) {
  const unmarshalled = unmarshall(data);
  
  // Recursively convert arrays from DynamoDB sets to JS Sets
  const convertToSets = (obj) => {
    for (const key in obj) {
      if (Array.isArray(obj[key])) {
        obj[key] = new Set(obj[key]);
      } else if (typeof obj[key] === 'object' && obj[key] !== null) {
        convertToSets(obj[key]);
      }
    }
    return obj;
  };
  
  return convertToSets(unmarshalled);
}

test('Marshall and Unmarshall with Custom Handler', () => {
  const raw = { 'anArray': new Set([ 'Apple', 'Mango' ]) };
  const marshalledResult = marshall(raw);
  
  const restoredData = unmarshallWithSets(marshalledResult);
  console.log(restoredData); // { anArray: Set(2) { 'Apple', 'Mango' } }
});

3. Update Your SDK Package

If you're getting an empty object instead of an array during unmarshalling, it's likely due to an outdated version of @aws-sdk/util-dynamodb. Update to the latest version to fix this bug:

npm update @aws-sdk/util-dynamodb

Key Takeaways

  • Marshalling works out of the box: the SDK converts JS Set objects to DynamoDB's SS/NS/BS types automatically.
  • Unmarshalling defaults to arrays, so you need explicit conversion if you want to work with Sets directly.
  • Updating your SDK package will resolve unexpected empty object issues caused by old bugs.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:33:10