В DynamoDB вы можете UpdateItem игнорировать неопределенные значения? - PullRequest
0 голосов
/ 28 ноября 2018

DynamoDB используется для управления запросами PATCH, где может быть предоставлено 1 или более свойств.Я хотел бы, чтобы эти свойства были обновлены, если они существуют в запросе, иначе игнорируются в обновлении.DocumentClient.update(params), где params:

    TableName: '...',
    Key: {...},
    UpdateExpression: `set 
      Cost = :Cost,
      Sales = :Sales,
      ...
    ExpressionAttributeValues: {
      ':Cost': get(requestBody, 'form.cost', undefined),
      ':Sales': get(requestBody, 'form.sales', undefined),
      ...
    }

Или это возможно только при манипулировании строками выражения ?

1 Ответ

0 голосов
/ 29 ноября 2018

Мне кажется, что я неправильно использую DynamoDB для этого многополевого PATCH, тем более что решение слишком сложное.

Оставьте это здесь на тот случай, если кто-то найдет это полезным или, что лучше, найдет более подходящее решение:

  let fieldsToUpdate = [
    // these are just string constants from another file
    [dynamoDbFields.cost, apiFields.cost],
    [dynamoDbFields.annualSales, apiFields.annualSales],
    ... ]
    // get the new DynamoDB value from the request body (it may not exist)
    .map(([dynamoDbField, apiField]) => [dynamoDbField, _.get(requestBody, apiField)])
    // filter any keys that are undefined on the request body
    .filter(([dynamoDbField, value]) => value !== undefined)

  // create a mapping of the field identifier (positional index in this case) to the DynamoDB value, e.g. {':0': '123'}
  let expressionAttributeValues = fieldsToUpdate.reduce((acc, [dynamoDbField, value], index) =>
    _.assignIn(acc, {[`:${index}`]: value}), {})

  // and create the reciprocal mapping of the identifier to the DynamoDB field name, e.g {ID: ':0'}
  let updateExpression = fieldsToUpdate.reduce((acc, [dynamoDbField], index) =>
    _.assignIn(acc, {[dynamoDbField]: `:${index}`}), {})

  const params = {
    TableName: TABLE_NAME,
    Key: {[dynamoDbFields.id]: _.get(requestBody, apiFields.id)},
    UpdateExpression: `set ${Object.entries(updateExpression).map((v) => v.join('=')).join(',')}`,
    ExpressionAttributeValues: expressionAttributeValues,
    ConditionExpression: `attribute_exists(${dynamoDbFields.id})`,
    ReturnValues: 'ALL_NEW'
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...