

# Trabalhar com itens e atributos no DynamoDB
<a name="WorkingWithItems"></a>

No Amazon DynamoDB, um *item* é uma coleção de atributos. Cada atributo tem um nome e um valor. Um valor de atributo pode ser uma escalar, um conjunto ou um tipo de documento. Para obter mais informações, consulte [Amazon DynamoDB: como funciona](HowItWorks.md).

O DynamoDB fornece quatro operações para a funcionalidade básica criar, ler, atualizar e excluir (CRUD). Todas essas operações são atômicas.
+ `PutItem`: criar um item.
+ `GetItem`: ler um item.
+ `UpdateItem`: atualizar um item.
+ `DeleteItem`: excluir um item.

Cada uma dessas operações exige que você especifique a chave primária do item com o qual deseja trabalhar. Por exemplo, para ler um item usando `GetItem`, você deve especificar a chave de partição e a chave de classificação (se aplicável) desse item.

Além das quatro operações CRUD básicas, o DynamoDB também fornece o seguinte:
+ `BatchGetItem`: ler até 100 itens de uma ou mais tabelas.
+ `BatchWriteItem`: criar ou excluir até 25 itens em uma ou mais tabelas.

Essas operações em lote combinam várias operações CRUD em uma única solicitação. Além disso, as operações em lote leem e gravam itens em paralelo para reduzir as latências de resposta.

Esta seção descreve como usar essas operações e inclui tópicos relacionados, como contadores atômicos e atualizações condicionais. Esta seção também inclui código de exemplo que usa os AWS SDKs. 

**Topics**
+ [Tamanhos e formatos de item do DynamoDB](CapacityUnitCalculations.md)
+ [Ler um item](#WorkingWithItems.ReadingData)
+ [Gravar um item](#WorkingWithItems.WritingData)
+ [Retornar valores](#WorkingWithItems.ReturnValues)
+ [Operações em lote](#WorkingWithItems.BatchOperations)
+ [Contadores atômicos](#WorkingWithItems.AtomicCounters)
+ [Gravações condicionais](#WorkingWithItems.ConditionalUpdate)
+ [Usar expressões no DynamoDB](Expressions.md)
+ [Usar a vida útil (TTL) no DynamoDB](TTL.md)
+ [Consultar tabelas no DynamoDB](Query.md)
+ [Verificar tabelas no DynamoDB](Scan.md)
+ [PartiQL: uma linguagem de consultas compatível com SQL para o Amazon DynamoDB](ql-reference.md)
+ [Trabalhar com itens: Java](JavaDocumentAPIItemCRUD.md)
+ [Trabalhar com itens: .NET](LowLevelDotNetItemCRUD.md)

## Ler um item
<a name="WorkingWithItems.ReadingData"></a>

Para ler um item de uma tabela do DynamoDB use a operação `GetItem`. Você deve fornecer o nome da tabela, juntamente com a chave primária do item desejado.

**Example**  
O exemplo da AWS CLI a seguir mostra como ler um item da tabela `ProductCatalog`.  

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}'
```

**nota**  
Com `GetItem`, você deve especificar a chave primária *inteira*, não apenas parte dela. Por exemplo, se uma tabela tiver uma chave primária composta (chave de partição e chave de classificação), você deverá fornecer um valor para a chave de partição e um valor para a chave de classificação.

A solicitação `GetItem` executa uma leitura final consistente, por padrão. Você pode usar o parâmetro `ConsistentRead` para solicitar uma leitura altamente consistente. (Isso consome unidades de capacidade de leitura adicionais, mas retorna a versão mais recente do item.)

`GetItem` retornará todos os atributos do item. Você pode usar uma *expressão de projeção* para retornar apenas alguns dos atributos. Para obter mais informações, consulte [Usar expressões de projeção no DynamoDB](Expressions.ProjectionExpressions.md).

Para retornar o número de unidades de capacidade de leitura consumidas por `GetItem`, defina o parâmetro `ReturnConsumedCapacity` como `TOTAL`.

**Example**  
O exemplo da AWS Command Line Interface (AWS CLI) a seguir mostra alguns dos parâmetros opcionais de `GetItem`.  

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --consistent-read \
    --projection-expression "Description, Price, RelatedItems" \
    --return-consumed-capacity TOTAL
```

## Gravar um item
<a name="WorkingWithItems.WritingData"></a>

Para criar, atualizar ou excluir um item em uma tabela do DynamoDB use uma das seguintes operações:
+ `PutItem`
+ `UpdateItem`
+ `DeleteItem`

Para cada uma dessas operações, você deve especificar a chave primária inteira, não apenas parte dela. Por exemplo, se uma tabela tiver uma chave primária composta (chave de partição e chave de classificação), você deve fornecer um valor para a chave de partição e um valor para a chave de classificação.

Para retornar o número de unidades de capacidade de gravação consumidas por qualquer uma dessas operações, defina o parâmetro `ReturnConsumedCapacity` de uma das seguintes formas: 
+ `TOTAL`: retorna o número total de unidades de capacidade de gravação consumidas.
+ `INDEXES`: retorna o número total de unidades de capacidade de gravação consumidas, com subtotais para a tabela e para todos os índices secundários que foram afetados pela operação.
+ `NONE`: nenhum detalhe da capacidade de gravação é retornado. (Esse é o padrão.)

### PutItem
<a name="WorkingWithItems.WritingData.PutItem"></a>

`PutItem` cria um novo item. Se um item com a mesma chave já existir na tabela, ele será substituído pelo novo item.

**Example**  
Gravar um novo item na tabela `Thread`. A chave primária de `Thread` consiste em `ForumName` (chave de partição) e `Subject` (chave de classificação).  

```
aws dynamodb put-item \
    --table-name Thread \
    --item file://item.json
```
Os argumentos de `--item` são armazenados no arquivo `item.json`.  

```
{
    "ForumName": {"S": "Amazon DynamoDB"},
    "Subject": {"S": "New discussion thread"},
    "Message": {"S": "First post in this thread"},
    "LastPostedBy": {"S": "fred@example.com"},
    "LastPostDateTime": {"S": "201603190422"}
}
```

### UpdateItem
<a name="WorkingWithItems.WritingData.UpdateItem"></a>

Se um item com a chave especificada não existir, `UpdateItem` criará um item. Caso contrário, ele modificará os atributos de um item existente.

Você usa uma *expressão de atualização* para especificar os atributos que deseja modificar e seus novos valores. Para obter mais informações, consulte [Usar expressões de atualização no DynamoDB](Expressions.UpdateExpressions.md). 

Na expressão de atualização, use valores de atributos de expressão como espaços reservados para os valores reais. Para obter mais informações, consulte [Usar valores de atributos de expressão no DynamoDB](Expressions.ExpressionAttributeValues.md).

**Example**  
Modifique vários atributos no item `Thread`. O parâmetro opcional `ReturnValues` mostra o item como ele aparece após a atualização. Para obter mais informações, consulte [Retornar valores](#WorkingWithItems.ReturnValues).  

```
aws dynamodb update-item \
    --table-name Thread \
    --key file://key.json \
    --update-expression "SET Answered = :zero, Replies = :zero, LastPostedBy = :lastpostedby" \
    --expression-attribute-values file://expression-attribute-values.json \
    --return-values ALL_NEW
```

Os argumentos de `--key` são armazenados no arquivo `key.json`.

```
{
    "ForumName": {"S": "Amazon DynamoDB"},
    "Subject": {"S": "New discussion thread"}
}
```

Os argumentos de `--expression-attribute-values` são armazenados no arquivo `expression-attribute-values.json`.

```
{
    ":zero": {"N":"0"},
    ":lastpostedby": {"S":"barney@example.com"}
}
```

### DeleteItem
<a name="WorkingWithItems.WritingData.DeleteItem"></a>

`DeleteItem` exclui o item com a chave especificada.

**Example**  
O exemplo da AWS CLI a seguir mostra como excluir o item `Thread`.  

```
aws dynamodb delete-item \
    --table-name Thread \
    --key file://key.json
```

## Retornar valores
<a name="WorkingWithItems.ReturnValues"></a>

Em alguns casos, talvez você queira que o DynamoDB retorne determinados valores de atributos como eles apareciam antes ou depois de modificados. As operações `PutItem`, `UpdateItem` e `DeleteItem` têm um parâmetro `ReturnValues` que você pode usar para retornar os valores de atributo antes ou depois que eles sejam modificados.

O valor padrão de `ReturnValues` é `NONE`, o que significa que o DynamoDB não retornará nenhuma informação sobre os atributos que foram modificados. 

Veja a seguir as outras configurações válidas de `ReturnValues`, organizadas pela operação da API do DynamoDB.

### PutItem
<a name="WorkingWithItems.ReturnValues.PutItem"></a>
+ `ReturnValues`: `ALL_OLD`
  + Se você substituir um item existente, `ALL_OLD` retornará o item inteiro, conforme ele aparecia antes da substituição.
  + Se você gravar um item que não existe, `ALL_OLD` não terá efeito.

### UpdateItem
<a name="WorkingWithItems.ReturnValues.UpdateItem"></a>

O uso mais comum de `UpdateItem` é para atualizar um item existente. No entanto, `UpdateItem` realmente executa um *upsert*, o que significa que ele criará o item automaticamente se ele ainda não existir.
+ `ReturnValues`: `ALL_OLD`
  + Se você atualizar um item existente, `ALL_OLD` retornará o item inteiro, conforme ele aparecia antes da atualização.
  + Se você atualizar um item que não existe (upsert), `ALL_OLD` não terá efeito.
+ `ReturnValues`: `ALL_NEW`
  + Se você atualizar um item existente, `ALL_NEW` retornará o item inteiro, conforme ele aparecia depois da atualização.
  + Se você atualizar um item que não existe (upsert), `ALL_NEW` retornará o item inteiro.
+ `ReturnValues`: `UPDATED_OLD`
  + Se você atualizar um item existente, `UPDATED_OLD` retornará apenas os atributos atualizados, como eles apareciam antes da atualização.
  + Se você atualizar um item que não existe (upsert), `UPDATED_OLD` não terá efeito.
+ `ReturnValues`: `UPDATED_NEW`
  + Se você atualizar um item existente, `UPDATED_NEW` retornará apenas os atributos afetados, como eles apareciam depois da atualização.
  + Se você atualizar um item que não existe (upsert), `UPDATED_NEW` retornará apenas os atributos atualizados, conforme eles aparecem após a atualização.

### DeleteItem
<a name="WorkingWithItems.ReturnValues.DeleteItem"></a>
+ `ReturnValues`: `ALL_OLD`
  + Se você excluir um item existente, `ALL_OLD` retornará o item inteiro, como ele aparecia antes de você excluí-lo.
  + Se você excluir um item que não existe, `ALL_OLD` não retornará nenhum dado.

## Operações em lote
<a name="WorkingWithItems.BatchOperations"></a>

Para aplicações que precisam ler ou gravar vários itens, o DynamoDB fornece as operações `BatchGetItem` e `BatchWriteItem`. Usar essas operações pode reduzir o número de round trips da rede da sua aplicação para o DynamoDB. Além disso, o DynamoDB executa as operações de leitura ou gravação individuais em paralelo. Suas aplicações se beneficiam desse paralelismo sem a necessidade de gerenciar a simultaneidade ou threading.

As operações em lote são essencialmente wrappers em torno de várias solicitações de leitura ou de gravação. Por exemplo, se uma solicitação `BatchGetItem` contiver cinco itens, o DynamoDB executará cinco operações `GetItem` em seu nome. Da mesma forma, se uma solicitação `BatchWriteItem` contiver duas solicitações Put e quatro solicitações Delete, o DynamoDB realizará duas solicitações `PutItem` e quatro `DeleteItem`.

Em geral, não há falha em uma operação em lote, a menos que haja falha em *todas* as solicitações no lote. Por exemplo, suponha que você execute uma operação `BatchGetItem`, mas que haja falha em uma das solicitações `GetItem` individuais no lote. Nesse caso, `BatchGetItem` retorna as chaves e os dados da solicitação `GetItem` com falha. As outras solicitações `GetItem` no lote não são afetadas.

### BatchGetItem
<a name="WorkingWithItems.BatchOperations.BatchGetItem"></a>

Uma única operação `BatchGetItem` pode conter até 100 solicitações `GetItem` individuais e recuperar até 16 MB de dados. Além disso, uma operação `BatchGetItem` pode recuperar itens de várias tabelas.

**Example**  
Recuperar dois itens da tabela `Thread` usando uma expressão de projeção para retornar apenas alguns dos atributos.  

```
aws dynamodb batch-get-item \
    --request-items file://request-items.json
```
Os argumentos de `--request-items` são armazenados no arquivo `request-items.json`.  

```
{
    "Thread": {
        "Keys": [
            {
                "ForumName":{"S": "Amazon DynamoDB"},
                "Subject":{"S": "DynamoDB Thread 1"}
            },
            {
                "ForumName":{"S": "Amazon S3"},
                "Subject":{"S": "S3 Thread 1"}
            }
        ],
        "ProjectionExpression":"ForumName, Subject, LastPostedDateTime, Replies"
    }
}
```

### BatchWriteItem
<a name="WorkingWithItems.BatchOperations.BatchWriteItem"></a>

A operação `BatchWriteItem` pode conter até 25 solicitações `PutItem` e `DeleteItem` individuais e gravar até 16 MB de dados. (O tamanho máximo de um item individual é 400 KB.) Além disso, uma operação `BatchWriteItem` pode inserir ou excluir itens em várias tabelas. 

**nota**  
`BatchWriteItem` não é compatível com solicitações `UpdateItem`.

**Example**  
Gravar dois itens na tabela `ProductCatalog`.  

```
aws dynamodb batch-write-item \
    --request-items file://request-items.json
```
Os argumentos de `--request-items` são armazenados no arquivo `request-items.json`.  

```
{
    "ProductCatalog": [
        {
            "PutRequest": {
                "Item": {
                    "Id": { "N": "601" },
                    "Description": { "S": "Snowboard" },
                    "QuantityOnHand": { "N": "5" },
                    "Price": { "N": "100" }
                }
            }
        },
        {
            "PutRequest": {
                "Item": {
                    "Id": { "N": "602" },
                    "Description": { "S": "Snow shovel" }
                }
            }
        }
    ]
}
```

## Contadores atômicos
<a name="WorkingWithItems.AtomicCounters"></a>

Você pode usar a operação `UpdateItem` para implementar um *contador atômico*, um atributo numérico que é incrementado incondicionalmente sem interferir em outras solicitações de gravação. (Todas as solicitações de gravação são aplicadas na ordem em que foram recebidas.) Com um contador atômico, as atualizações não são imutáveis. Em outras palavras, o valor numérico é incrementado ou reduzido cada vez que você chama `UpdateItem`. Se o valor de incremento usado para atualizar o contador atômico for positivo, isso poderá causar contagem a mais. Se o valor do incremento for negativo, isso poderá causar contagem a menos.

Você pode usar um contador atômico para rastrear o número de visitantes de um site. Neste caso, sua aplicação poderia incrementar um valor numérico, independentemente do seu valor atual. Se houve falha em uma operação `UpdateItem`, a aplicação poderá simplesmente tentar a operação novamente. Isso arriscaria atualizar o contador duas vezes, mas provavelmente você poderia tolerar uma pequena contagem a mais ou a menos de visitantes do site.

Um contador atômico não seria apropriado onde uma contagem a mais ou a menos não pudesse ser tolerada (por exemplo, em uma aplicação bancária). Nesse caso, é mais seguro usar uma atualização condicional em vez de um contador atômico.

Para obter mais informações, consulte [Incrementar e reduzir atributos numéricos](Expressions.UpdateExpressions.md#Expressions.UpdateExpressions.SET.IncrementAndDecrement).

**Example**  
O exemplo da AWS CLI a seguir incrementa o `Price` de um produto em 5. Neste exemplo, sabia-se que o item existia antes da atualização do contador. Como `UpdateItem` não é idempotente, o `Price` aumenta cada vez que você executa esse código.   

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id": { "N": "601" }}' \
    --update-expression "SET Price = Price + :incr" \
    --expression-attribute-values '{":incr":{"N":"5"}}' \
    --return-values UPDATED_NEW
```

## Gravações condicionais
<a name="WorkingWithItems.ConditionalUpdate"></a>

Por padrão, as operações de gravação do DynamoDB (`PutItem` e `DeleteItem`) são *incondicionais*: cada operação substitui um item existente que tem a chave primária especificada.

Opcionalmente, o DynamoDB é compatível com gravações condicionais dessas operações. Uma gravação condicional terá êxito somente se os atributos de item atenderem a uma ou mais condições esperadas. Caso contrário, um erro será retornado.

As gravações condicionais comparam suas condições com a versão atualizada mais recentemente do item. Observe que, se o item não existisse anteriormente ou se a operação bem-sucedida mais recente referente a esse item tivesse sido uma exclusão, a gravação condicional não encontraria nenhum item anterior.

 Gravações condicionais são úteis em muitas situações. Por exemplo, talvez você queira que uma operação `PutItem` tenha êxito somente se já não houver um item com a mesma chave primária. Ou você poderia impedir que uma operação `UpdateItem` modificasse um item, se um de seus atributos tivesse um determinado valor.

As gravações condicionais são úteis nos casos em que vários usuários tentam modificar o mesmo item. Considere o diagrama a seguir, no qual dois usuários (Alice e Bob) estão trabalhando com o mesmo item de uma tabela do DynamoDB.

![Os usuários Alice e Bob tentam modificar um item com Id 1, demonstrando a necessidade de gravações condicionais.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/update-no-condition.png)


Suponha que Alice usa a AWS CLI para atualizar o atributo `Price` para 8.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --expression-attribute-values file://expression-attribute-values.json
```

Os argumentos de `--expression-attribute-values` são armazenados no arquivo `expression-attribute-values.json`:

```
{
    ":newval":{"N":"8"}
}
```

Agora, suponha que Bob emita uma solicitação `UpdateItem` semelhante mais tarde, mas altere o `Price` para 12. Para Bob, o parâmetro `--expression-attribute-values` tem a seguinte aparência.

```
{
    ":newval":{"N":"12"}
}
```

A solicitação de Bob é bem-sucedida, mas a atualização anterior de Alice é perdida.

Para solicitar uma condicional `PutItem`, `DeleteItem` ou `UpdateItem`, especifique uma expressão de condição. Uma *expressão de condição* é uma string que contém nomes de atributos, operadores condicionais e funções internas. A expressão inteira deve ser avaliada como verdadeira. Caso contrário, haverá falha na operação.

Agora, considere o seguinte diagrama que mostra como gravações condicionais impediriam que a atualização de Alice fosse substituída.

![Gravação condicional impedindo que a atualização do usuário Bob sobrescreva a alteração da usuária Alice no mesmo item.](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/update-yes-condition.png)


Alice primeiro tenta atualizar `Price` para 8, mas somente se o `Price` atual for 10.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --condition-expression "Price = :currval" \
    --expression-attribute-values file://expression-attribute-values.json
```

Os argumentos de `--expression-attribute-values` são armazenados no arquivo `expression-attribute-values.json`.

```
{
    ":newval":{"N":"8"},
    ":currval":{"N":"10"}
}
```

A atualização de Alice é bem-sucedida porque a condição é avaliada como verdadeira.

Em seguida, Bob tenta atualizar o `Price` para 12, mas somente se o `Price` atual for 10. Para Bob, o parâmetro `--expression-attribute-values` tem a seguinte aparência.

```
{
    ":newval":{"N":"12"},
    ":currval":{"N":"10"}
}
```

Como Alice mudou o `Price` para 8 anteriormente, a expressão de condição é avaliada como falsa, e há falha na atualização de Bob.

Para obter mais informações, consulte [Exemplo de expressão de condição do DynamoDB na CLI](Expressions.ConditionExpressions.md).

### Idempotência de gravação condicional
<a name="WorkingWithItems.ConditionalWrites.Idempotence"></a>

As gravações condicionais podem ser *imutáveis* se a verificação condicional estiver no mesmo atributo que está sendo atualizado. Isso significa que o DynamoDB realiza uma determinada solicitação de gravação somente se certos valores de atributo no item corresponderem aos valores estimados no momento da solicitação. 

Por exemplo, suponha que você emita uma solicitação de `UpdateItem` para aumentar o `Price` de um item em 3, mas somente se o `Price` atual for 20. Depois de enviar a solicitação, mas antes de obter os resultados de volta, ocorre um erro de rede e você não sabe se a solicitação teve êxito. Como essa gravação condicional é imutável, você pode tentar novamente a mesma solicitação de `UpdateItem`, e o DynamoDB atualizará o item somente se `Price` for igual a 20 no momento.

### Unidades de capacidade consumidas por gravações condicionais
<a name="WorkingWithItems.ConditionalWrites.ReturnConsumedCapacity"></a>

Se uma `ConditionExpression` for avaliada como false durante uma gravação condicional, o DynamoDB ainda consumirá capacidade de gravação da tabela. A quantidade consumida depende do tamanho do item existente (ou no mínimo 1). Por exemplo, se um item existente tiver 300 kb e o item que você está tentando criar ou atualizar tiver 310 kb, as unidades de capacidade de gravação consumidas serão 300 se a condição falhar e 310 se a condição for bem-sucedida. Se for um item novo (nenhum item existente), as unidades de capacidade de gravação consumidas serão 1 se a condição falhar e 310 se a condição for bem-sucedida.

**nota**  
As operações de gravação consomem apenas unidades de capacidade de *gravação*. Elas nunca consomem unidades de capacidade de *leitura*.

Uma gravação condicional com falha retorna uma `ConditionalCheckFailedException`. Quando isso ocorre, você não recebe nenhuma informação na resposta sobre a capacidade de gravação que foi consumida.

Para retornar o número de unidades de capacidade de gravação consumidas durante uma gravação condicional, você deve usar o parâmetro `ReturnConsumedCapacity`:
+ `TOTAL`: retorna o número total de unidades de capacidade de gravação consumidas.
+ `INDEXES`: retorna o número total de unidades de capacidade de gravação consumidas, com subtotais para a tabela e para todos os índices secundários que foram afetados pela operação.
+ `NONE`: nenhum detalhe da capacidade de gravação é retornado. (Esse é o padrão.)

  

**nota**  
Ao contrário de um índice secundário global, um índice secundário local compartilha a capacidade de throughput provisionada com sua tabela. A atividade de leitura e gravação em um índice secundário local consome a capacidade de throughput provisionado da tabela.