Búsqueda de sitios web

node.js - SDK de Dynamo JS v3: ¿cómo uso un array en ExpressionAttributeValues (con Typescript)?


import { [various] } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';  


// see https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/index.html
const dynamoClient = new DynamoDB({ region: parameters.AWS_REGION });
const dynamoDocClient = DynamoDBDocumentClient.from(dynamoClient);  

...

const params: UpdateItemCommandInput = {
    TableName: dynamoCollections.divisionVariety,
    Key: { divisionID: { N: `${divisionID}` } },
    UpdateExpression:
        'SET accounts = LIST_APPEND(IF_NOT_EXISTS(accounts, []), :accountsAndBrands)',
    ExpressionAttributeValues: {
        ':accountsAndBrands': accounts,  // <=========== HERE
    },
    ReturnValues: 'UPDATED_NEW',
};

try {
    const data = await dynamoDocClient.send(
        new UpdateItemCommand(params)
    );
    ...


Necesito insertar o actualizar en la propiedad accounts de un documento existente. El argumento accounts es un array de POJOs.

El problema es que estoy recibiendo TS2322: Type 'unknown[]' is not assignable to type 'AttributeValue'. en ':accountsAndBrands': accounts. Según la documentación, debería recibir el proceso de marshaling de accounts. Intenté agregar un as, pero no pensé que funcionaría y no funciona: TS2352: Conversion of type 'unknown[]' to type 'AttributeValue' may be a mistake. Si agrego un as unknown obtengo un error de marshaling en serializeAws_json1_0AttributeValue. Si simplemente hago ts-ignore en la línea problemática, también obtengo un error de marshaling.

Si reemplazo el objeto accounts con una cadena simple, todavía obtengo TS2322: Type 'string' is not assignable to type 'AttributeValue'.

¿Cómo hago para que Typescript y el DocumentClient marshaling coexistan aquí? Realmente parece que las definiciones de tipos no permiten un arreglo donde se espera una interfaz AttributeValue.

Los documentos dicen que debería obtener el marshalling adecuado gratis:

El cliente de documentos permite a los desarrolladores el uso de tipos nativos de JavaScript en lugar de AttributeValues para simplificar la experiencia de desarrollo en JavaScript con Amazon DynamoDB. Los objetos de JavaScript pasados como parámetros se transforman en las formas AttributeValue requeridas por Amazon DynamoDB. Las respuestas de DynamoDB se transforman en objetos de JavaScript simples por el DocumentClient. El DocumentClient no acepta AttributeValues a favor de los tipos nativos de JavaScript.

documentos :

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/index.html

actualización: En realidad logré que un insert funcionara, pero tuve que usar un objeto que cumpliera con AttributeValue: L: [{ S: 'Cookies' }, { S: 'Coffee' }, { N: '3.14159' }]. Pero cuando revisé Dynamo, los valores no se habían deserializado, se almacenaron como [{ S: 'Cookies' }, { S: 'Coffee' }, { N: '3.14159' }] en lugar de ['Cookies', 'Coffee', 3.14159]. Esto parece un error.

Respuesta #1

Parece que estás mezclando el comando de actualización y los tipos de entrada de @aws-sdk/client-dynamodb y @aws-sdk/lib-dynamodb.

Si no quieres usar el valor del atributo, deberías usar UpdateCommand y UpdateCommandInput de @aws-sdk/lib-dynamodb. Debería funcionar así:

import { [various] } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient, UpdateCommand, UpdateCommandInput } from '@aws-sdk/lib-dynamodb';  

const dynamoClient = new DynamoDB({ region: parameters.AWS_REGION });
const dynamoDocClient = DynamoDBDocumentClient.from(dynamoClient);  

...
const params: UpdateCommandInput = {   // from @aws-sdk/lib-dynamodb
    TableName: dynamoCollections.divisionVariety,
    Key: { divisionID: { N: `${divisionID}` } },
    UpdateExpression:
        'SET accounts = LIST_APPEND(IF_NOT_EXISTS(accounts, []), :accountsAndBrands)',
    ExpressionAttributeValues: {
        ':accountsAndBrands': accounts,  // <=========== THIS SHOULD BE ACCEPTED NOW
    },
    ReturnValues: 'UPDATED_NEW',
};

try {
    const data = await dynamoDocClient.send(
        new UpdateCommand(params)   // from @aws-sdk/lib-dynamodb
    );
    ...

Artículos relacionados