如何从 DynamoDB 的 AttributeValue 格式实例化 Dynamoose 模型?

How to instantiate Dynamoose Model from DynamoDB's AttributeValue format?

我正在使用 Dynamodb 流对添加或修改到我的 table 的记录进行一些处理。我也在我的应用程序中使用 Dynamoose 模型。

Dynamodb 流事件将事件对象传递到我的 node.js lambda 处理程序,其中包括对象 record.dynamoDb.NewImagerecord.dynamoDb.OldImage。但是,这些对象采用 DynamoDB 的 AttributeValue 格式,包括所有数据类型('S' 字符串),而不是普通的 javascript 对象。所以 record.id 变成 record.id.S.

Dynamoose 模型允许您从对象实例化模型,如下所示:new Model(object)。但是,它希望该参数是一个普通对象。

我知道 Dynamoose 有一个 dynamodb 解析器,我认为它是 Schema.prototype.dynamodbparse()。然而,这并没有像预期的那样工作。

import { DYNAMODB_EVENT } from '../../constant';
import _get from 'lodash/get';
import { Entry } from '../../model/entry';
import { applyEntry } from './applyEntry';

async function entryStream(event) {
  await Promise.all(
    event.Records.map(async record => {
      // If this record is being deleted, do nothing
      if (DYNAMODB_EVENT.Remove === record.eventName) {
        return;
      }

      // What I've tried:
      let entry = new Entry(record.dynamodb.NewImage);

      // What I wish I could do
      entry = new Entry(Entry.schema.dynamodbparse(record.dynamodb.newImage));
      await applyEntry(entry);
    })
  );
}

export const handler = entryStream;

那么有没有办法从 DynamoDB 的 AttributeValue 格式实例化 Dynamoose 模型?还有其他人这样做吗?

另一种方法是,我只是从 record 中提取密钥,然后使用 Model.get({ id: idFromEvent }); 访问数据库,但我认为这样效率不高,因为记录只是从流中递给我。

我在传递给 Dynamoose 之前使用 AWS.DynamoDB.Converter.unmarshall 解析对象解决了这个问题。

import { DYNAMODB_EVENT } from '../../constant';
import _get from 'lodash/get';
import { Entry } from '../../model/entry';
import { applyEntry } from './applyEntry';

// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/Converter.html#unmarshall-property
var AWS = require('aws-sdk');
var parseDynamo = AWS.DynamoDB.Converter.unmarshall;

async function entryStream(event) {
  await Promise.all(
    event.Records.map(async record => {
      // If this record is being deleted, do nothing
      if (DYNAMODB_EVENT.Remove === record.eventName) {
        return;
      }

      entry = new Entry(parseDynamo(record.dynamodb.newImage));
      await applyEntry(entry);
    })
  );
}

export const handler = entryStream;