

# 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)

# Tamanhos e formatos de item do DynamoDB
<a name="CapacityUnitCalculations"></a>

As tabelas do DynamoDB são sem esquema, exceto para a chave primária. Portanto, os itens em uma tabela podem ter atributos, tamanhos e tipos de dados diferentes.

O tamanho total de um item é a soma dos tamanhos de seus nomes e valores de atributos, somado a qualquer sobrecarga aplicável como descrito abaixo. Você pode usar as seguintes diretrizes para estimar os tamanhos de atributo:
+ Strings são Unicode com codificação binária UTF-8. O tamanho de uma string é *(número de bytes codificados por UTF-8 do nome do atributo) \$1 (número de bytes codificados em UTF-8)*.
+ Os números são de tamanho variável, com até 38 dígitos significativos. Zeros iniciais e finais são cortados. O tamanho de um número é aproximadamente *(número de bytes codificados por UTF-8 do nome do atributo) \$1 (1 byte por dois dígitos significativos) \$1 (1 byte)*.
+ Um valor binário deve ser codificado no formato base64 antes que possa ser enviado para o DynamoDB, mas o tamanho de byte bruto do valor é usado para calcular o tamanho. O tamanho de um atributo binário é *(número de bytes codificados por UTF-8 do nome do atributo) \$1 (número de bytes brutos).*
+ O tamanho de um atributo nulo ou de um atributo booliano é *(número de bytes codificados por UTF-8 do nome do atributo) \$1 (1 byte)*.
+ Um atributo do tipo `List` ou `Map` requer 3 bytes de sobrecarga, independentemente de seu conteúdo. O tamanho de uma `List` ou um `Map` é *(número de bytes codificados por UTF-8 do nome do atributo) \$1 soma (tamanho dos elementos aninhados) \$1 (3 bytes)*. O tamanho de uma `List` ou um `Map` vazio é *(número de bytes codificados por UTF-8 do nome do atributo) \$1 (3 bytes)*.
+ Cada elemento da `List` ou do `Map` também requer 1 byte de sobrecarga.

**nota**  
Recomendamos que você escolha nomes mais curtos para os atributos. Isso ajuda a reduzir a quantidade de armazenamento necessária, mas também pode reduzir a quantidade de RCU/WCUs usada.

Para fins de faturamento de armazenamento, cada item inclui uma sobrecarga de armazenamento por item que depende dos recursos ativados.
+ Todos os itens no DynamoDB requerem 100 bytes de sobrecarga de armazenamento para indexação.
+ Alguns recursos do DynamoDB (tabelas globais, transações, captura de dados de alteração para o Kinesis Data Streams com o DynamoDB) exigem sobrecarga de armazenamento adicional para contabilizar atributos criados pelo sistema resultantes da ativação desses recursos. Por exemplo, tabelas globais exigem 48 bytes adicionais de sobrecarga de armazenamento.

## 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.

# Usar expressões no DynamoDB
<a name="Expressions"></a>

No Amazon DynamoDB, você pode usar *expressões* para especificar quais atributos devem ser lidos em um item, gravar dados quando uma condição é atendida, especificar como atualizar um item, definir consultas e filtrar os resultados de uma consulta.

Esta tabela descreve a gramática de expressão básica e os tipos de expressão disponíveis.


| Tipo de expressão | Descrição | 
| --- | --- | 
| Expressão de projeção | Uma expressão de projeção identifica os atributos que você deseja recuperar de um item ao usar operações como GetItem, Query ou Scan. | 
| Expressão de condição | Uma expressão de condição determina quais itens devem ser modificados ao usar as operações PutItem, UpdateItem e DeleteItem. | 
| Expressão de atualização | Uma expressão de atualização especifica como UpdateItem modificará os atributos de um item. Por exemplo, definindo um valor escalar ou removendo elementos de uma lista ou de um mapa. | 
| Expressão de condição principal | Uma expressão de condição principal determina quais itens uma consulta lerá em uma tabela ou índice. | 
| Expressão de filtro | Uma expressão de filtro determina quais itens dos resultados de Query devem ser retornados para você. Todos os outros resultados serão descartados. | 

Para saber mais sobre sintaxe de expressão e mais detalhes sobre cada tipo de expressão, consulte as seções a seguir.

**Topics**
+ [Referir-se a atributos de item ao usar expressões no DynamoDB](Expressions.Attributes.md)
+ [Nomes (aliases) de atributo de expressão no DynamoDB](Expressions.ExpressionAttributeNames.md)
+ [Usar valores de atributos de expressão no DynamoDB](Expressions.ExpressionAttributeValues.md)
+ [Usar expressões de projeção no DynamoDB](Expressions.ProjectionExpressions.md)
+ [Usar expressões de atualização no DynamoDB](Expressions.UpdateExpressions.md)
+ [Expressões de condição e filtro, operadores e funções no DynamoDB](Expressions.OperatorsAndFunctions.md)
+ [Exemplo de expressão de condição do DynamoDB na CLI](Expressions.ConditionExpressions.md)

**nota**  
Para fins de compatibilidade com versões anteriores, o DynamoDB também aceita parâmetros condicionais que não usam expressões. Para obter mais informações, consulte [Parâmetros condicionais legados do DynamoDB](LegacyConditionalParameters.md).  
Novas aplicações devem usar expressões em vez de parâmetros herdados.

# Referir-se a atributos de item ao usar expressões no DynamoDB
<a name="Expressions.Attributes"></a>

Esta seção descreve como consultar atributos de item em uma expressão no Amazon DynamoDB. Você pode trabalhar com qualquer atributo, mesmo se ele estiver profundamente aninhado dentro de várias listas e mapas.

**Topics**
+ [Atributos de nível superior](#Expressions.Attributes.TopLevelAttributes)
+ [Atributos aninhados](#Expressions.Attributes.NestedAttributes)
+ [Caminhos de documentos](#Expressions.Attributes.NestedElements.DocumentPathExamples)

**Um item de exemplo: ProductCatalog**  
Os exemplos desta página usam o item de amostra a seguir na tabela `ProductCatalog`. (Esta tabela é descrita na seção [Exemplos de tabelas e dados para uso no DynamoDB](AppendixSampleTables.md).)

```
{
    "Id": 123,
    "Title": "Bicycle 123",
    "Description": "123 description",
    "BicycleType": "Hybrid",
    "Brand": "Brand-Company C",
    "Price": 500,
    "Color": ["Red", "Black"],
    "ProductCategory": "Bicycle",
    "InStock": true,
    "QuantityOnHand": null,
    "RelatedItems": [
        341,
        472,
        649
    ],
    "Pictures": {
        "FrontView": "http://example.com/products/123_front.jpg",
        "RearView": "http://example.com/products/123_rear.jpg",
        "SideView": "http://example.com/products/123_left_side.jpg"
    },
    "ProductReviews": {
	    "FiveStar": [
	    		"Excellent! Can't recommend it highly enough! Buy it!",
	    		"Do yourself a favor and buy this."
	    ],
	    "OneStar": [
	    		"Terrible product! Do not buy this."
	    ]
    },
    "Comment": "This product sells out quickly during the summer",
    "Safety.Warning": "Always wear a helmet"
 }
```

Observe o seguinte:
+ O valor da chave de partição (`Id`) é `123`. Não há chave de classificação.
+ A maioria dos atributos têm tipos de dados escalares, como `String`, `Number`, `Boolean` e `Null`.
+ Um atributo (`Color`) é um `String Set`.
+ Os atributos a seguir são tipos de dados de documento:
  + Uma lista de `RelatedItems`. Cada elemento é um `Id` de um produto relacionado.
  + Um mapa de `Pictures`. Cada elemento é uma breve descrição de uma imagem, juntamente com um URL para o arquivo de imagem correspondente.
  + Um mapa de `ProductReviews`. Cada elemento representa uma classificação e uma lista de avaliações correspondentes a essa classificação. Inicialmente, esse mapa é preenchido com avaliações de cinco estrelas e de uma estrela.

## Atributos de nível superior
<a name="Expressions.Attributes.TopLevelAttributes"></a>

Um atributo será considerado como de *nível superior* se ele não estiver incorporado a outro atributo. Para o item do `ProductCatalog`, os atributos de nível superior são os seguintes:
+ `Id`
+ `Title`
+ `Description`
+ `BicycleType`
+ `Brand`
+ `Price`
+ `Color`
+ `ProductCategory`
+ `InStock`
+ `QuantityOnHand`
+ `RelatedItems`
+ `Pictures`
+ `ProductReviews`
+ `Comment`
+ `Safety.Warning`

Todos esses atributos de nível superior são escalares, exceto `Color` (lista), `RelatedItems` (lista), `Pictures` (mapa) e `ProductReviews` (mapa).

## Atributos aninhados
<a name="Expressions.Attributes.NestedAttributes"></a>

Um atributo é considerado *aninhado* se ele estiver incorporado a outro atributo. Para acessar um atributo aninhado, utiliza-se *operadores de cancelamento de referência*:
+ `[n]`: para elementos de lista
+ `.` (ponto): para elementos de mapa

### Acesso a elementos de lista
<a name="Expressions.Attributes.NestedElements.AccessingListElements"></a>

O operador de desreferência de um elemento de lista é **[*N*]**, onde *n* é o número do elemento. Os elementos de lista são baseados em zero, portanto, [0] representa o primeiro elemento na lista, [1] representa o segundo, e assim por diante. Veja alguns exemplos:
+ `MyList[0]`
+ `AnotherList[12]`
+ `ThisList[5][11]`

O próprio elemento `ThisList[5]` é uma lista aninhada. Portanto, `ThisList[5][11]` refere-se ao décimo segundo elemento na lista.

O número dentro de colchetes deve ser um inteiro não negativo. Portanto, as seguintes expressões são inválidas:
+ `MyList[-1]`
+ `MyList[0.4]`

### Acessar elementos de mapas
<a name="Expressions.Attributes.NestedElements.AccessingMapElements"></a>

O operador de cancelamento de referência de um elemento de mapa é **.** (um ponto). Use um ponto como um separador entre os elementos em um mapa:
+ `MyMap.nestedField`
+ `MyMap.nestedField.deeplyNestedField`

## Caminhos de documentos
<a name="Expressions.Attributes.NestedElements.DocumentPathExamples"></a>

Em uma expressão, você usa um *caminho de documento* para informar ao DynamoDB onde encontrar um atributo. Para um atributo de nível superior, o caminho do documento é simplesmente o nome do atributo. Para um atributo aninhado, você pode construir o caminho do documento usando operadores de cancelamento de referência.

Veja a seguir alguns exemplos de caminhos de documentos. (Consulte o item mostrado em [Referir-se a atributos de item ao usar expressões no DynamoDB](#Expressions.Attributes).)
+ Um atributo escalar de nível superior.

   `Description`
+ Um atributo de lista de nível superior. (Isso retorna a lista inteira, não apenas alguns dos elementos.)

  `RelatedItems`
+ O terceiro elemento na lista `RelatedItems`. (Lembre-se de que os elementos de lista são baseadas em zero.)

  `RelatedItems[2]`
+ A imagem da visão frontal do produto.

  `Pictures.FrontView`
+ Todas as críticas de cinco estrelas.

  `ProductReviews.FiveStar`
+ A primeira das críticas de cinco estrelas.

  `ProductReviews.FiveStar[0]`

**nota**  
A profundidade máxima de um caminho de documento é 32. Portanto, o número de operadores de cancelamento de referência em um caminho não pode exceder esse limite.

É possível usar qualquer nome de atributo em um caminho de documento, desde ele que cumpra estes requisitos:
+ O primeiro caractere deve ser `a-z` ou `A-Z` e ou `0-9`
+ O segundo caractere (se presente) deve ser `a-z`, `A-Z`

**nota**  
Se um nome de atributo não cumprir essas exigências, você deverá definir um nome de atributo de expressão como um espaço reservado.

Para obter mais informações, consulte [Nomes (aliases) de atributo de expressão no DynamoDB](Expressions.ExpressionAttributeNames.md).

# Nomes (aliases) de atributo de expressão no DynamoDB
<a name="Expressions.ExpressionAttributeNames"></a>

Um *nome de atributo de expressão* é um alias (ou espaço reservado) usado em uma expressão do Amazon DynamoDB como alternativa ao nome de atributo real. Um nome de atributo de expressão deve começar com um sinal de cerquilha (`#`) seguido de um ou mais caracteres alfanuméricos. O sublinhado (`_`) também é permitido.

Esta seção descreve várias situações em que você precisa usar nomes de atributos de expressão.

**nota**  
Os exemplos desta seção usam a AWS Command Line Interface (AWS CLI). 

**Topics**
+ [Palavras reservadas](#Expressions.ExpressionAttributeNames.ReservedWords)
+ [Nomes de atributos com caracteres especiais](#Expressions.ExpressionAttributeNames.AttributeNamesContainingSpecialCharacters)
+ [Atributos aninhados](#Expressions.ExpressionAttributeNames.NestedAttributes)
+ [Consultar nomes de atributo de forma repetida](#Expressions.ExpressionAttributeNames.RepeatingAttributeNames)

## Palavras reservadas
<a name="Expressions.ExpressionAttributeNames.ReservedWords"></a>

Algumas vezes, pode ser necessário escrever uma expressão que contém um nome de atributo que está em conflito com uma palavra reservada do DynamoDB. (Para obter uma lista completa de palavras reservadas, consulte [Palavras reservadas no DynamoDB](ReservedWords.md).)

Por exemplo, haveria falha no seguinte exemplo da AWS CLI porque `COMMENT` é uma palavra reservada.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "Comment"
```

Para resolver esse problema, substitua `Comment` por um nome de atributo de expressão, como `#c`. A `#` (cerquilha) é obrigatória e indica que esse é um espaço reservado para um nome de atributo. O exemplo da AWS CLI agora deve ter a seguinte aparência.

```
aws dynamodb get-item \
     --table-name ProductCatalog \
     --key '{"Id":{"N":"123"}}' \
     --projection-expression "#c" \
     --expression-attribute-names '{"#c":"Comment"}'
```

**nota**  
Se o nome de um atributo começar com um número, contiver um espaço ou incluir uma palavra reservada, você *deverá* usar um nome de atributo de expressão para substituir esse nome de atributo na expressão.

## Nomes de atributos com caracteres especiais
<a name="Expressions.ExpressionAttributeNames.AttributeNamesContainingSpecialCharacters"></a>

Em uma expressão, um ponto (“.”) é interpretado como um caractere de separação em um caminho de documento. No entanto, o DynamoDB também permite que você use um ponto e outros caracteres especiais, como um hífen (“-”) como parte do nome de um atributo. Isso pode ser ambíguo em alguns casos. Para ilustrar, vamos supor que você queira recuperar o atributo `Safety.Warning` de um item do `ProductCatalog` (consulte [Referir-se a atributos de item ao usar expressões no DynamoDB](Expressions.Attributes.md)).

Suponha que você queira acessar `Safety.Warning` usando uma expressão de projeção.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "Safety.Warning"
```

O DynamoDB retorna um resultado vazio, em vez da string esperada (“”). ("`Always wear a helmet`"). Isso ocorre porque o DynamoDB interpreta um ponto em uma expressão como um separador de caminho de documento. Neste caso, defina um nome de atributo de expressão (por exemplo, `#sw`) como um substituto para `Safety.Warning`. Você poderia usar a seguinte expressão de projeção.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#sw" \
    --expression-attribute-names '{"#sw":"Safety.Warning"}'
```

Em seguida, o DynamoDB deverá retornar o resultado correto.

**nota**  
Se o nome de um atributo contiver um ponto (“.”) ou um hífen (“-”), você *deverá* usar um nome de atributo de expressão para substituir o nome desse atributo na expressão.

## Atributos aninhados
<a name="Expressions.ExpressionAttributeNames.NestedAttributes"></a>

Suponha que você queira acessar o atributo `ProductReviews.OneStar` aninhado. No nome de atributo de expressão, o DynamoDB trata o ponto (“.”) como um caractere no nome de um atributo. Para consultar o atributo aninhado, defina um nome de atributo de expressão para cada elemento no caminho do documento:
+ `#pr — ProductReviews`
+ `#1star — OneStar`

Você poderia usar `#pr.#1star` para a expressão de projeção.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#pr.#1star"  \
    --expression-attribute-names '{"#pr":"ProductReviews", "#1star":"OneStar"}'
```

Em seguida, o DynamoDB deverá retornar o resultado correto.

## Consultar nomes de atributo de forma repetida
<a name="Expressions.ExpressionAttributeNames.RepeatingAttributeNames"></a>

Os nomes de atributo de expressão são úteis quando você precisa consultar o mesmo nome de atributo repetidamente. Por exemplo, considere a seguinte expressão para recuperar algumas das revisões de um item do `ProductCatalog`.

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "ProductReviews.FiveStar, ProductReviews.ThreeStar, ProductReviews.OneStar"
```

Para tornar isso mais conciso, você pode substituir `ProductReviews` por um nome de atributo de expressão, como `#pr`. A expressão revisada agora teria a seguinte aparência.
+  `#pr.FiveStar, #pr.ThreeStar, #pr.OneStar` 

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#pr.FiveStar, #pr.ThreeStar, #pr.OneStar" \
    --expression-attribute-names '{"#pr":"ProductReviews"}'
```

Caso defina um nome de atributo de expressão, você deverá usá-lo de forma consistente na expressão inteira. Além disso, não é possível omitir o símbolo `#`. 

# Usar valores de atributos de expressão no DynamoDB
<a name="Expressions.ExpressionAttributeValues"></a>

Os *valores de atributo de expressão* no Amazon DynamoDB atuam como variáveis. Eles substituem os valores reais que você deseja comparar; isto é, valores que talvez não conheça antes do tempo de execução. Um valor de atributo de expressão deve começar com um sinal de dois pontos (`:`) seguido por um ou mais caracteres alfanuméricos.

Por exemplo, suponha que você quisesse retornar todos os itens de `ProductCatalog` que estão disponíveis em `Black` e custam `500` ou menos. Você poderia usar uma operação `Scan` com uma expressão de filtro, como neste exemplo da AWS Command Line Interface (AWS CLI).

```
aws dynamodb scan \
    --table-name ProductCatalog \
    --filter-expression "contains(Color, :c) and Price <= :p" \
    --expression-attribute-values file://values.json
```

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

```
{
    ":c": { "S": "Black" },
    ":p": { "N": "500" }
}
```

Caso defina um valor de atributo de expressão, você deverá usá-lo de forma consistente na expressão inteira. Além disso, não é possível omitir o símbolo `:`. 

Os valores de atributo de expressão são usados com expressões de condições de chaves, expressões de condições, expressões de atualização e expressões de filtro.

# Usar expressões de projeção no DynamoDB
<a name="Expressions.ProjectionExpressions"></a>

Para ler dados de uma tabela, você pode usar operações como `GetItem`, `Query`ou `Scan`. O Amazon DynamoDB retornará todos os atributos de item por padrão. Para obter somente alguns, em vez de todos os atributos, use uma expressão de projeção.

Uma *expressão de projeção* é uma string que identifica os atributos que você deseja. Para recuperar um único atributo, especifique o seu nome. Para vários atributos, os nomes devem ser separados por vírgulas.

Veja a seguir alguns exemplos de expressões de projeção, com base no item do `ProductCatalog` em [Referir-se a atributos de item ao usar expressões no DynamoDB](Expressions.Attributes.md):
+ Um único atributo de nível superior.

  `Title `
+ Três atributos de nível superior. O DynamoDB recupera o conjunto `Color` inteiro.

  `Title, Price, Color`
+ Quatro atributos de nível superior. O DynamoDB retorna todo o conteúdo de `RelatedItems` e `ProductReviews`.

  `Title, Description, RelatedItems, ProductReviews`

**nota**  
A expressão de projeção não afeta o consumo de throughput provisionado. O DynamoDB determina as unidades de capacidade consumidas com base no tamanho do item, e não na quantidade de dados que são retornados para uma aplicação.

**Palavras reservadas e caracteres especiais**

O DynamoDB inclui palavras reservadas e caracteres especiais. O DynamoDB permite usar essas palavras reservadas e caracteres especiais nos nomes, mas é recomendável evitar, pois será necessário usar aliases sempre que esses nomes forem utilizados em uma expressão. Para obter uma lista completa, consulte [Palavras reservadas no DynamoDB](ReservedWords.md).

Você precisará usar nomes de atributo de expressão no lugar do nome real se: 
+ O nome do atributo estiver na lista de palavras reservadas do DynamoDB.
+ O nome do atributo não atender ao requisito de que o primeiro caractere deve ser `a-z` ou `A-Z` e que o segundo caractere (se houver) deve ser `a-Z`, `A-Z` ou `0-9`.
+ O nome do atributo contiver **\$1** (cerquilha) ou **:** (dois-pontos).

O exemplo de AWS CLI a seguir mostra como usar uma expressão de projeção com uma operação `GetItem`. Essa expressão de projeção recupera um atributo escalar de nível superior (`Description`), o primeiro elemento em uma lista (`RelatedItems[0]`) e uma lista aninhada em um mapa (`ProductReviews.FiveStar`).

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '"Id": { "N": "123" } \
    --projection-expression "Description, RelatedItems[0], ProductReviews.FiveStar"
```

O JSON a seguir seria retornado para este exemplo.

```
{
    "Item": {
        "Description": {
            "S": "123 description"
        },
        "ProductReviews": {
            "M": {
                "FiveStar": {
                    "L": [
                        {
                            "S": "Excellent! Can't recommend it highly enough! Buy it!"
                        },
                        {
                            "S": "Do yourself a favor and buy this."
                        }
                    ]
                }
            }
        },
        "RelatedItems": {
            "L": [
                {
                    "N": "341"
                }
            ]
        }
    }
}
```

# Usar expressões de atualização no DynamoDB
<a name="Expressions.UpdateExpressions"></a>

A ação `UpdateItem` atualiza um item existente ou adiciona um item novo à tabela, caso ele ainda não exista. Você deve fornecer a chave do item que deseja atualizar. Você também deve fornecer uma expressão de atualização indicando os atributos que deseja modificar e os valores que deseja atribuir a eles. 

Uma *expressão de atualização* especifica como `UpdateItem` modificará os atributos de um item. Por exemplo, definindo um valor escalar ou removendo elementos de uma lista ou de um mapa.

Veja a seguir um resumo da sintaxe para expressões de atualização.

```
update-expression ::=
    [ SET action [, action] ... ]
    [ REMOVE action [, action] ...]
    [ ADD action [, action] ... ]
    [ DELETE action [, action] ...]
```

Uma expressão de atualização consiste em uma ou mais cláusulas. Cada cláusula começa com uma palavra-chave `SET`, `REMOVE`, `ADD` ou `DELETE`. Você pode incluir qualquer uma dessas cláusulas em uma expressão de atualização, em qualquer ordem. No entanto, cada palavra-chave de ação pode aparecer apenas uma vez.

Dentro de cada cláusula há uma ou mais ações, separadas por vírgulas. Cada ação representa uma modificação de dados.

Os exemplos desta seção se baseiam no item `ProductCatalog` mostrado em [Usar expressões de projeção no DynamoDB](Expressions.ProjectionExpressions.md).

Os tópicos abaixo abrangem alguns casos de uso diferentes da ação `SET`.

**Topics**
+ [SET: modificar ou adicionar atributos de um item](#Expressions.UpdateExpressions.SET)
+ [REMOVE: excluir atributos de um item](#Expressions.UpdateExpressions.REMOVE)
+ [ADD: atualizar números e conjuntos](#Expressions.UpdateExpressions.ADD)
+ [DELETE: remover elementos de um conjunto](#Expressions.UpdateExpressions.DELETE)
+ [Usar várias expressões de atualização](#Expressions.UpdateExpressions.Multiple)

## SET: modificar ou adicionar atributos de um item
<a name="Expressions.UpdateExpressions.SET"></a>

Use a ação `SET` em uma expressão de atualização para adicionar um ou mais atributos a um item. Se qualquer um desses atributos já existir, eles serão substituídos pelos novos valores. Se você deseja evitar a substituição de um atributo existente, pode usar `SET` com a função `if_not_exists`. A função `if_not_exists` é específica à ação `SET` e só pode ser usada em uma expressão de atualização.

Quando você usa `SET` para atualizar um elemento de lista, o conteúdo desse elemento é substituído pelos novos dados especificados. Se o elemento ainda não existir, `SET` acrescentará o novo elemento ao final da lista.

Se você adicionar vários elementos em uma única operação `SET`, estes serão classificados por número de elemento.

Você também pode usar `SET` para adicionar ou subtrair de um atributo do tipo `Number`. Para executar várias ações `SET`, separe-as com vírgulas.

No seguinte resumo de sintaxe:
+ O elemento *path* é o caminho do documento para o item.
+ Um elemento **operando** pode ser o caminho de um documento para um item ou uma função.

```
set-action ::=
    path = value

value ::=
    operand
    | operand '+' operand
    | operand '-' operand

operand ::=
    path | function

function ::=
    if_not_exists (path, value)
```

Se o item não contiver um atributo no caminho especificado, `if_not_exists` será avaliado como `value`. Caso contrário, será avaliado como `path`.

A seguinte operação `PutItem` cria um item de exemplo ao qual os exemplos fazem referência.

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json
```

Os argumentos de `--item` são armazenados no arquivo `item.json`. (Para simplificar, apenas alguns atributos de item são usados.)

```
{
    "Id": {"N": "789"},
    "ProductCategory": {"S": "Home Improvement"},
    "Price": {"N": "52"},
    "InStock": {"BOOL": true},
    "Brand": {"S": "Acme"}
}
```

**Topics**
+ [Modificar atributos](#Expressions.UpdateExpressions.SET.ModifyingAttributes)
+ [Adicionar listas e mapas](#Expressions.UpdateExpressions.SET.AddingListsAndMaps)
+ [Adicionar elementos a uma lista](#Expressions.UpdateExpressions.SET.AddingListElements)
+ [Adicionar atributos de mapa aninhados](#Expressions.UpdateExpressions.SET.AddingNestedMapAttributes)
+ [Incrementar e reduzir atributos numéricos](#Expressions.UpdateExpressions.SET.IncrementAndDecrement)
+ [Acrescentar elementos a uma lista](#Expressions.UpdateExpressions.SET.UpdatingListElements)
+ [Impedir substituições de um atributo existente](#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites)

### Modificar atributos
<a name="Expressions.UpdateExpressions.SET.ModifyingAttributes"></a>

**Example**  
Atualize os atributos `ProductCategory` e `Price`.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET ProductCategory = :c, Price = :p" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":c": { "S": "Hardware" },
    ":p": { "N": "60" }
}
```

**nota**  
Na operação `UpdateItem`, `--return-values ALL_NEW` faz com que o DynamoDB retorne o item como ele aparece após a atualização.

### Adicionar listas e mapas
<a name="Expressions.UpdateExpressions.SET.AddingListsAndMaps"></a>

**Example**  
Adicione uma nova lista e um novo mapa.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems = :ri, ProductReviews = :pr" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":ri": {
        "L": [
            { "S": "Hammer" }
        ]
    },
    ":pr": {
        "M": {
            "FiveStar": {
                "L": [
                    { "S": "Best product ever!" }
                ]
            }
        }
    }
}
```

### Adicionar elementos a uma lista
<a name="Expressions.UpdateExpressions.SET.AddingListElements"></a>

**Example**  
Adicione um novo atributo à lista `RelatedItems`. (Lembre-se de que elementos de lista são baseados em zero e, portanto, [0] representa o primeiro elemento da lista, [1] representa o segundo, e assim por diante.)  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems[1] = :ri" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":ri": { "S": "Nails" }
}
```

**nota**  
Quando você usa `SET` para atualizar um elemento de lista, o conteúdo desse elemento é substituído pelos novos dados especificados. Se o elemento ainda não existir, `SET` acrescentará o novo elemento ao final da lista.  
Se você adicionar vários elementos em uma única operação `SET`, estes serão classificados por número de elemento.

### Adicionar atributos de mapa aninhados
<a name="Expressions.UpdateExpressions.SET.AddingNestedMapAttributes"></a>

**Example**  
Adicione alguns atributos de mapa aninhados.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #pr.#5star[1] = :r5, #pr.#3star = :r3" \
    --expression-attribute-names file://names.json \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-names` são armazenados no arquivo `names.json`.  

```
{
    "#pr": "ProductReviews",
    "#5star": "FiveStar",
    "#3star": "ThreeStar"
}
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":r5": { "S": "Very happy with my purchase" },
    ":r3": {
        "L": [
            { "S": "Just OK - not that great" }
        ]
    }
}
```

**Importante**  
Não será possível atualizar os atributos do mapa aninhado se o mapa pai não existir. Se você tentar atualizar um atributo aninhado (por exemplo, `ProductReviews.FiveStar`) quando o mapa pai (`ProductReviews`) não existir, o DynamoDB exibirá `ValidationException` com a mensagem *“O caminho do documento fornecido na expressão de atualização é inválido para atualização”*.  
Ao criar itens que terão atributos de mapa aninhados atualizados posteriormente, inicialize mapas vazios para os atributos principais. Por exemplo:  

```
{
    "Id": {"N": "789"},
    "ProductReviews": {"M": {}},
    "Metadata": {"M": {}}
}
```
Isso permite que você atualize atributos aninhados, como `ProductReviews.FiveStar`, sem erros.

### Incrementar e reduzir atributos numéricos
<a name="Expressions.UpdateExpressions.SET.IncrementAndDecrement"></a>

Você pode adicionar ou subtrair de um atributo numérico existente. Para fazer isso, use os operadores `+` (mais) e `-` (menos).

**Example**  
Diminua o valor do `Price` de um item.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = Price - :p" \
    --expression-attribute-values '{":p": {"N":"15"}}' \
    --return-values ALL_NEW
```
Para aumentar o valor do `Price`, você usa o operador `+` na expressão de atualização.

### Acrescentar elementos a uma lista
<a name="Expressions.UpdateExpressions.SET.UpdatingListElements"></a>

É possível adicionar elementos ao final de uma lista. Para fazer isso, use `SET` com a função `list_append`. (O nome da função diferencia maiúsculas de minúsculas.) A função `list_append` é específica à ação `SET` e só pode ser usada em uma expressão de atualização. A sintaxe é a seguinte.
+ `list_append (list1, list2)`

A função utiliza duas listas como entrada e acrescenta todos os elementos de `list2` a ` list1`.

**Example**  
Em [Adicionar elementos a uma lista](#Expressions.UpdateExpressions.SET.AddingListElements), você cria a lista `RelatedItems` e a preenche com dois elementos: `Hammer` e `Nails`. Na sequência, você acrescenta mais dois elementos ao final de `RelatedItems`.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #ri = list_append(#ri, :vals)" \
    --expression-attribute-names '{"#ri": "RelatedItems"}' \
    --expression-attribute-values file://values.json  \
    --return-values ALL_NEW
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":vals": {
        "L": [
            { "S": "Screwdriver" },
            {"S": "Hacksaw" }
        ]
    }
}
```
Por fim, você acrescenta mais um elemento ao *início* de `RelatedItems`. Para fazer isso, alterne a ordem dos elementos de `list_append`. (Lembre-se de que `list_append` usa duas listas como entrada e acrescenta a segunda lista à primeira.)  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #ri = list_append(:vals, #ri)" \
    --expression-attribute-names '{"#ri": "RelatedItems"}' \
    --expression-attribute-values '{":vals": {"L": [ { "S": "Chisel" }]}}' \
    --return-values ALL_NEW
```
Agora, o atributo `RelatedItems` resultante contém cinco elementos, na seguinte ordem: `Chisel`, `Hammer`, `Nails`, `Screwdriver`, `Hacksaw`.

### Impedir substituições de um atributo existente
<a name="Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites"></a>

**Example**  
Defina o `Price` de um item, mas somente se o item ainda não tiver um atributo `Price`. (Se o atributo `Price` já existir, não acontecerá nada.)  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = if_not_exists(Price, :p)" \
    --expression-attribute-values '{":p": {"N": "100"}}' \
    --return-values ALL_NEW
```

## REMOVE: excluir atributos de um item
<a name="Expressions.UpdateExpressions.REMOVE"></a>

Use a ação `REMOVE` em uma expressão de atualização para remover um ou mais atributos de um item no Amazon DynamoDB. Para executar várias ações `REMOVE`, separe-as com vírgulas.

O seguinte é um resumo da sintaxe de `REMOVE` em uma expressão de atualização. O único operando é o caminho do documento do atributo que você deseja remover.

```
remove-action ::=
    path
```

**Example**  
Remova alguns atributos de um item. (Se os atributos não existirem, nada acontecerá.)  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE Brand, InStock, QuantityOnHand" \
    --return-values ALL_NEW
```

### Remover elementos de uma lista
<a name="Expressions.UpdateExpressions.REMOVE.RemovingListElements"></a>

É possível usar `REMOVE` para excluir elementos individuais de uma lista.

**Example**  
Em [Acrescentar elementos a uma lista](#Expressions.UpdateExpressions.SET.UpdatingListElements), você modifica um atributo da lista (`RelatedItems`) de forma que ele contenha cinco elementos:   
+ `[0]`—`Chisel`
+ `[1]`—`Hammer`
+ `[2]`—`Nails`
+ `[3]`—`Screwdriver`
+ `[4]`—`Hacksaw`
O exemplo da AWS Command Line Interface (AWS CLI) a seguir exclui `Hammer` e `Nails` da lista.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE RelatedItems[1], RelatedItems[2]" \
    --return-values ALL_NEW
```
Depois que `Hammer` e `Nails` forem removidos, os elementos restantes serão deslocados. Agora, a lista contém o seguinte:  
+ `[0]`—`Chisel`
+ `[1]`—`Screwdriver`
+ `[2]`—`Hacksaw`

## ADD: atualizar números e conjuntos
<a name="Expressions.UpdateExpressions.ADD"></a>

**nota**  
Em geral, recomendamos usar `SET` em vez de `ADD` para garantir operações idempotentes.

Use a ação `ADD` em uma expressão de atualização para adicionar um novo atributo e seus valores a um item.

Se o atributo já existir, o comportamento de `ADD` dependerá do tipo de dados do atributo:
+ Se o atributo for um número, e o valor que você está adicionando também for um número, esse valor será matematicamente adicionado ao atributo existente. (Se o valor for um número negativo, ele será subtraído do atributo existente.)
+ Se o atributo for um conjunto, e o valor que você está adicionando também for um conjunto, esse valor será acrescentado ao conjunto existente.

**nota**  
A ação `ADD` oferece suporte apenas a tipos de dados de número e conjunto.

Para executar várias ações `ADD`, separe-as com vírgulas.

No seguinte resumo de sintaxe:
+ O elemento *path* é o caminho do documento para um atributo. O atributo deve ser um `Number` ou um tipo de dados de conjunto. 
+ O elemento *value* é um número que você deseja adicionar ao atributo (para tipos de dados `Number`) ou um conjunto a ser acrescentado ao atributo (para tipos de conjunto).

```
add-action ::=
    path value
```

Os tópicos abaixo abrangem alguns casos de uso diferentes da ação `ADD`.

**Topics**
+ [Adicionar um número](#Expressions.UpdateExpressions.ADD.Number)
+ [Adicionar elementos a um conjunto](#Expressions.UpdateExpressions.ADD.Set)

### Adicionar um número
<a name="Expressions.UpdateExpressions.ADD.Number"></a>

Suponha que o atributo `QuantityOnHand` não exista. O exemplo da AWS CLI a seguir define `QuantityOnHand` como 5.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD QuantityOnHand :q" \
    --expression-attribute-values '{":q": {"N": "5"}}' \
    --return-values ALL_NEW
```

Agora que `QuantityOnHand` existe, você pode executar novamente o exemplo para incrementar `QuantityOnHand` em 5 de cada vez.

### Adicionar elementos a um conjunto
<a name="Expressions.UpdateExpressions.ADD.Set"></a>

Suponha que o atributo `Color` não exista. O exemplo da AWS CLI a seguir define `Color` como um conjunto de strings com dois elementos.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD Color :c" \
    --expression-attribute-values '{":c": {"SS":["Orange", "Purple"]}}' \
    --return-values ALL_NEW
```

Agora que `Color` existe, você pode adicionar mais elementos a ele.

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD Color :c" \
    --expression-attribute-values '{":c": {"SS":["Yellow", "Green", "Blue"]}}' \
    --return-values ALL_NEW
```

## DELETE: remover elementos de um conjunto
<a name="Expressions.UpdateExpressions.DELETE"></a>

**Importante**  
A ação `DELETE` oferece suporte apenas a tipos de dados `Set`.

Use a ação `DELETE` em uma expressão de atualização para remover um ou mais elementos de um conjunto. Para executar várias ações `DELETE`, separe-as com vírgulas.

No seguinte resumo de sintaxe:
+ O elemento *path* é o caminho do documento para um atributo. Esse atributo deve ser um tipo de dados de conjunto.
+ O elemento *subset* é um ou mais elementos que você deseja excluir de *path*. Você deve especificar o elemento *subset* como um tipo set.

```
delete-action ::=
    path subset
```

**Example**  
Em [Adicionar elementos a um conjunto](#Expressions.UpdateExpressions.ADD.Set), você cria o conjunto de tipo string `Color`. Este exemplo remove alguns dos elementos desse conjunto.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "DELETE Color :p" \
    --expression-attribute-values '{":p": {"SS": ["Yellow", "Purple"]}}' \
    --return-values ALL_NEW
```

## Usar várias expressões de atualização
<a name="Expressions.UpdateExpressions.Multiple"></a>

É possível usar várias ações em uma única expressão de atualização. Todas as referências a atributos são resolvidas em relação ao estado do item antes que qualquer uma das ações seja aplicada.

**Example**  
Dado um item `{"id": "1", "a": 1, "b": 2, "c": 3}`, a seguinte expressão remove `a` e muda os valores de `b` e `c`:  

```
aws dynamodb update-item \
    --table-name test \
    --key '{"id":{"S":"1"}}' \
    --update-expression "REMOVE a SET b = a, c = b" \
    --return-values ALL_NEW
```
O resultado é `{"id": "1", "b": 1, "c": 2}`. Embora `a` seja removida e `b` reatribuída na mesma expressão, ambas as referências retornam os valores originais.

**Example**  
Se quiser modificar o valor de um atributo e remover outro completamente, você poderá usar uma ação SET e uma REMOVE em uma única declaração. Essa operação reduziria o valor de `Price` para 15 e, ao mesmo tempo, removeria o atributo `InStock` do item.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = Price - :p REMOVE InStock" \
    --expression-attribute-values '{":p": {"N":"15"}}' \
    --return-values ALL_NEW
```

**Example**  
Se quiser adicionar a uma lista e, ao mesmo tempo, alterar o valor de outro atributo, você poderá usar duas ações SET em uma única declaração. Essa operação adicionaria “Unhas” ao atributo da lista `RelatedItems` e também definiria o valor de `Price` como 21.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems[1] = :newValue, Price = :newPrice" \
    --expression-attribute-values '{":newValue": {"S":"Nails"}, ":newPrice": {"N":"21"}}'  \
    --return-values ALL_NEW
```

# Expressões de condição e filtro, operadores e funções no DynamoDB
<a name="Expressions.OperatorsAndFunctions"></a>

Para manipular dados em uma tabela do DynamoDB, use as operações `PutItem`, `UpdateItem` e `DeleteItem`. Para essas operações de manipulação de dados, é possível especificar uma expressão de condição para determinar quais itens devem ser modificados. Se a expressão de condição for avaliada como verdadeira, a operação terá êxito. Caso contrário, haverá falha na operação.

Esta seção aborda as funções e palavras-chave integradas para escrever expressões de filtro e expressões de condição no Amazon DynamoDB. Para obter informações mais detalhadas sobre funções e programação com o DynamoDB, consulte [Programação com o DynamoDB e os AWS SDKs](Programming.md) e a [Referência da API do DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/).

**Topics**
+ [Sintaxe para expressões de filtro e de condição](#Expressions.OperatorsAndFunctions.Syntax)
+ [Fazer comparações](#Expressions.OperatorsAndFunctions.Comparators)
+ [Funções](#Expressions.OperatorsAndFunctions.Functions)
+ [Avaliações lógicas](#Expressions.OperatorsAndFunctions.LogicalEvaluations)
+ [Parênteses](#Expressions.OperatorsAndFunctions.Parentheses)
+ [Precedência em condições](#Expressions.OperatorsAndFunctions.Precedence)

## Sintaxe para expressões de filtro e de condição
<a name="Expressions.OperatorsAndFunctions.Syntax"></a>

No seguinte resumo de sintaxe, um *operando* pode ser o seguinte: 
+ Um nome de atributo de nível superior, como `Id`, `Title`, `Description` ou `ProductCategory`
+ Um caminho de documento que faz referência a um atributo aninhado

```
condition-expression ::=
      operand comparator operand
    | operand BETWEEN operand AND operand
    | operand IN ( operand (',' operand (, ...) ))
    | function
    | condition AND condition
    | condition OR condition
    | NOT condition
    | ( condition )

comparator ::=
    =
    | <>
    | <
    | <=
    | >
    | >=

function ::=
    attribute_exists (path)
    | attribute_not_exists (path)
    | attribute_type (path, type)
    | begins_with (path, substr)
    | contains (path, operand)
    | size (path)
```

## Fazer comparações
<a name="Expressions.OperatorsAndFunctions.Comparators"></a>

Use esses comparadores para comparar um operando com um único valor:
+ `a = b`: verdadeiro se *a* for igual a *b*.
+ `a <> b`: verdadeiro se *a* não for igual a *b*.
+ `a < b`: verdadeiro se *a* for menor que *b*.
+ `a <= b`: verdadeiro se *a* for menor que ou igual a *b*.
+ `a > b`: verdadeiro se *a* for maior que *b*.
+ `a >= b`: verdadeiro se *a* for maior ou igual a *b*.

Use as palavras-chave `BETWEEN` e `IN` para comparar um operando com um intervalo de valores ou com uma lista enumerada de valores:
+ `a BETWEEN b AND c`: verdadeiro se *a* for maior ou igual a *b* e menor ou igual a *c*.
+ `a IN (b, c, d) `: verdadeiro se *a* for igual a qualquer um dos valores na lista; por exemplo, *b*, *c* ou *d*. A lista pode conter até 100 valores, separados por vírgulas.

## Funções
<a name="Expressions.OperatorsAndFunctions.Functions"></a>

Use as funções a seguir para determinar se um atributo existe em um item ou para avaliar o valor de um atributo. Esses nomes de funções diferenciam maiúsculas de minúsculas. Para um atributo aninhado, você deve fornecer o caminho completo do documento.


****  

| Função | Descrição | 
| --- | --- | 
|  `attribute_exists (path)`  | True se o item contiver o atributo especificado por `path`. Exemplo: verificar se um item na tabela `Product` tem uma imagem de vista lateral. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 
|  `attribute_not_exists (path)`  | True se o atributo especificado por `path` não existir no item. Exemplo: verificar se um item tem um atributo `Manufacturer`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 
|  `attribute_type (path, type)`  |  True se o atributo no caminho especificado for de um tipo de dados específico. O parâmetro `type` deve ser um dos seguintes: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Você deve usar um valor de atributo de expressão para o parâmetro `type`. Exemplo: verificar se o atributo `QuantityOnHand` é do tipo Lista. Neste exemplo, `:v_sub` é um espaço reservado para a string `L`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Você deve usar um valor de atributo de expressão para o parâmetro `type`.   | 
|  `begins_with (path, substr)`  |  Verdadeiro se o atributo especificado por `path` começar com uma substring específica. Exemplo: verificar se os primeiros caracteres do URL da imagem de vista frontal são `http://`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) O valor do atributo de expressão `:v_sub` é um espaço reservado para `http://`.  | 
|  `contains (path, operand)`  | Verdadeiro se o atributo especificado por `path` for um dos seguintes: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Se o atributo especificado por `path` for `String`, o `operand` deve ser `String`. Se o atributo especificado por `path` for um `Set`, o `operand` deverá ser o tipo de elemento do conjunto. O caminho e o operando devem ser distintos. Isto é, `contains (a, a)` retorna um erro. Exemplo: verificar se o atributo `Brand` contém a substring `Company`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) O valor do atributo de expressão `:v_sub` é um espaço reservado para `Company`. Exemplo: verificar se o produto está disponível em vermelho. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) O valor do atributo de expressão `:v_sub` é um espaço reservado para `Red`. | 
|  `size (path)`  | Retorna um número que representa o tamanho de um atributo. Veja a seguir os tipos de dados válidos para uso com `size`.  Se o atributo for do tipo `String`, `size` retornará o comprimento da string. Exemplo: verificar se a string `Brand` é menor ou igual a 20 caracteres. O valor do atributo de expressão `:v_sub` é um espaço reservado para `20`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Se o atributo for do tipo `Binary`, `size` retornará o número de bytes no valor do atributo. Exemplo: suponha que o item de `ProductCatalog` tenha um atributo binário chamado `VideoClip`, que contém um curto vídeo sobre o produto em uso. A seguinte expressão verifica se `VideoClip` excede 64.000 bytes. O valor do atributo de expressão `:v_sub` é um espaço reservado para `64000`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Se o atributo for de um tipo de dados de `Set`, `size` retornará o número de elementos no conjunto.  Exemplo: verificar se o produto está disponível em mais de uma cor. O valor do atributo de expressão `:v_sub` é um espaço reservado para `1`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Se o atributo for do tipo `List` ou `Map`, `size` retornará o número de elementos filho. Exemplo: verificar se o número de revisões `OneStar` excedeu um determinado limite. O valor do atributo de expressão `:v_sub` é um espaço reservado para `3`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 

## Avaliações lógicas
<a name="Expressions.OperatorsAndFunctions.LogicalEvaluations"></a>

Use as palavras-chave `AND`, `OR` e `NOT` para executar avaliações lógicas. Na lista a seguir, *a* e *b* representam condições a serem avaliadas.
+ `a AND b`: verdadeiro se *a* e *b* forem ambos verdadeiros.
+ `a OR b`: verdadeiro se *a* ou *b* ou ambos forem verdadeiros.
+ `NOT a`: verdadeiro se *a* for falso. Falso se *a* for verdadeiro.

Veja a seguir um exemplo de código de AND em uma operação.

`dynamodb-local (*)> select * from exprtest where a > 3 and a < 5;`

## Parênteses
<a name="Expressions.OperatorsAndFunctions.Parentheses"></a>

Use parênteses para alterar a precedência de uma avaliação lógica. Por exemplo, suponha que as condições *a* e *b* sejam verdadeiras e que a condição *c* seja falsa. As expressões a seguir são avaliadas como verdadeiras:
+ `a OR b AND c`

No entanto, se você colocar uma condição entre parênteses, ela será avaliada primeiro. Por exemplo, o seguinte é avaliado como falso:
+  `(a OR b) AND c`

**nota**  
Você pode aninhar parênteses em uma expressão. Os componentes mais internos são avaliados primeiro.

Veja a seguir um exemplo de código com parênteses em uma avaliação lógica.

`dynamodb-local (*)> select * from exprtest where attribute_type(b, string) or ( a = 5 and c = “coffee”);`

## Precedência em condições
<a name="Expressions.OperatorsAndFunctions.Precedence"></a>

 O DynamoDB avalia as condições da esquerda para a direita usando as seguintes regras de precedência:
+ `= <> < <= > >=`
+ `IN`
+ `BETWEEN`
+ `attribute_exists attribute_not_exists begins_with contains`
+ Parênteses
+ `NOT`
+ `AND`
+ `OR`

# Exemplo de expressão de condição do DynamoDB na CLI
<a name="Expressions.ConditionExpressions"></a>

Veja a seguir alguns exemplos da AWS Command Line Interface (AWS CLI) para uso de expressões de condição. Estes exemplos se baseiam na tabela `ProductCatalog`, que foi apresentada em [Referir-se a atributos de item ao usar expressões no DynamoDB](Expressions.Attributes.md). A chave de partição dessa tabela é `Id`. Não há uma chave de classificação. A seguinte operação `PutItem` cria um item `ProductCatalog` de amostra ao qual os exemplos se referem.

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json
```

Os argumentos de `--item` são armazenados no arquivo `item.json`. (Para simplificar, apenas alguns atributos de item são usados.)

```
{
    "Id": {"N": "456" },
    "ProductCategory": {"S": "Sporting Goods" },
    "Price": {"N": "650" }
}
```

**Topics**
+ [Put condicional](#Expressions.ConditionExpressions.PreventingOverwrites)
+ [Exclusões condicionais](#Expressions.ConditionExpressions.AdvancedComparisons)
+ [Atualizações condicionais](#Expressions.ConditionExpressions.SimpleComparisons)
+ [Exemplos de expressão condicional](#Expressions.ConditionExpressions.ConditionalExamples)

## Put condicional
<a name="Expressions.ConditionExpressions.PreventingOverwrites"></a>

A operação `PutItem` substitui um item com a mesma chave primária (se houver). Se quiser evitar isso, use uma expressão de condição. Isso permitirá que a gravação continue apenas se o item em questão ainda não tiver a mesma chave primária.

O exemplo a seguir usa `attribute_not_exists()` para verificar se a chave primária existe na tabela antes de tentar a operação de gravação. 

**nota**  
Se a chave primária consistir em uma chave de partição (pk) e uma chave de classificação (sk), o parâmetro verificará se `attribute_not_exists(pk)` E `attribute_not_exists(sk)` são avaliados como uma declaração inteiramente verdadeira ou falsa antes de tentar a operação de gravação.

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json \
    --condition-expression "attribute_not_exists(Id)"
```

Se a expressão de condição for avaliada como falsa, o DynamoDB retornará uma mensagem de erro The conditional request failed (Falha na solicitação condicional).

**nota**  
Para obter mais informações sobre `attribute_not_exists` e outras funções, consulte [Expressões de condição e filtro, operadores e funções no DynamoDB](Expressions.OperatorsAndFunctions.md).

## Exclusões condicionais
<a name="Expressions.ConditionExpressions.AdvancedComparisons"></a>

Para realizar uma exclusão condicional, use uma operação `DeleteItem` com uma expressão de condição. A expressão de condição deve ser avaliada como verdadeira para que a operação tenha êxito; caso contrário, haverá falha na operação.

Considere o item definido acima.

Suponha que você queira excluir o item, mas somente nas seguintes condições:
+  O valor de `ProductCategory` é “Sporting Goods” ou “Gardening Supplies”.
+  O valor de `Price` está entre 500 e 600.

O exemplo a seguir tenta excluir o item.

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"456"}}' \
    --condition-expression "(ProductCategory IN (:cat1, :cat2)) and (Price between :lo and :hi)" \
    --expression-attribute-values file://values.json
```

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

```
{
    ":cat1": {"S": "Sporting Goods"},
    ":cat2": {"S": "Gardening Supplies"},
    ":lo": {"N": "500"},
    ":hi": {"N": "600"}
}
```

**nota**  
Na expressão de condição, o caractere `:` (dois pontos) indica um *valor de atributo de expressão*: um espaço reservado para um valor real. Para obter mais informações, consulte [Usar valores de atributos de expressão no DynamoDB](Expressions.ExpressionAttributeValues.md).  
Para obter mais informações sobre `IN`, `AND` e outras palavras-chave, consulte [Expressões de condição e filtro, operadores e funções no DynamoDB](Expressions.OperatorsAndFunctions.md).

Neste exemplo, a comparação `ProductCategory` é avaliada como true, mas a comparação `Price` é avaliada como false. Isso faz com que a expressão de condição seja avaliada como falsa e haja falha na operação `DeleteItem`.

## Atualizações condicionais
<a name="Expressions.ConditionExpressions.SimpleComparisons"></a>

Para realizar uma atualização condicional, use uma operação `UpdateItem` com uma expressão de condição. A expressão de condição deve ser avaliada como verdadeira para que a operação tenha êxito. Caso contrário, haverá falha na operação.

**nota**  
`UpdateItem` também oferece suporte a *expressões de atualização*, nas quais você especifica as modificações que deseja fazer em um item. Para obter mais informações, consulte [Usar expressões de atualização no DynamoDB](Expressions.UpdateExpressions.md).

Suponha que você tenha começado com o item definido acima.

O exemplo a seguir realiza uma operação `UpdateItem`. Ele tenta reduzir o `Price` de um produto em 75, mas a expressão de condição impedirá a atualização se o `Price` atual for menor ou igual a 500.

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

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

```
{
    ":discount": { "N": "75"},
    ":limit": {"N": "500"}
}
```

Se o valor inicial de `Price` for 650, a operação `UpdateItem` reduzirá o `Price` para 575. Se você executar a operação `UpdateItem` novamente, o valor de `Price` será reduzido para 500. Se você executá-la uma terceira vez, a expressão de condição será avaliada como falsa, e haverá falha na atualização.

**nota**  
Na expressão de condição, o caractere `:` (dois pontos) indica um *valor de atributo de expressão*: um espaço reservado para um valor real. Para obter mais informações, consulte [Usar valores de atributos de expressão no DynamoDB](Expressions.ExpressionAttributeValues.md).  
Para obter mais informações sobre "*>*" e outros operadores, consulte [Expressões de condição e filtro, operadores e funções no DynamoDB](Expressions.OperatorsAndFunctions.md).

## Exemplos de expressão condicional
<a name="Expressions.ConditionExpressions.ConditionalExamples"></a>

Para obter mais informações sobre as funções usadas nos exemplos a seguir, consulte [Expressões de condição e filtro, operadores e funções no DynamoDB](Expressions.OperatorsAndFunctions.md). Se você quiser saber mais sobre como especificar diferentes tipos de atributo em uma expressão, consulte [Referir-se a atributos de item ao usar expressões no DynamoDB](Expressions.Attributes.md). 

### Verificar atributos em um item
<a name="Expressions.ConditionExpressions.CheckingForAttributes"></a>

Você pode verificar a existência (ou inexistência) de qualquer atributo. Se a expressão da condição for avaliada como verdadeira, a operação terá êxito. Caso contrário, haverá falha.

O exemplo a seguir usa `attribute_not_exists` para excluir um produto apenas se ele não tiver um atributo `Price`.

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_not_exists(Price)"
```

O DynamoDB também fornece uma função `attribute_exists`. O exemplo a seguir excluirá um produto somente se ele tiver recebido revisões ruins.

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_exists(ProductReviews.OneStar)"
```

### Verificar tipo de atributo
<a name="Expressions.ConditionExpressions.CheckingForAttributeType"></a>

É possível verificar o tipo de dados de um valor de atributo usando a função `attribute_type`. Se a expressão da condição for avaliada como verdadeira, a operação terá êxito. Caso contrário, haverá falha.

O exemplo a seguir usa `attribute_type` para excluir um produto somente se ele tiver um atributo `Color` do tipo Conjunto de strings. 

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_type(Color, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

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

```
{
    ":v_sub":{"S":"SS"}
}
```

### Verificar valor inicial da string
<a name="Expressions.ConditionExpressions.CheckingBeginsWith"></a>

É possível verificar se um valor de atributo String começa com uma substring específica usando a função `begins_with`. Se a expressão da condição for avaliada como verdadeira, a operação terá êxito. Caso contrário, haverá falha. 

O exemplo a seguir usará `begins_with` para excluir um produto somente se o elemento `FrontView` do mapa `Pictures` começar com um valor específico.

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "begins_with(Pictures.FrontView, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

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

```
{
    ":v_sub":{"S":"http://"}
}
```

### Verificar um elemento em um conjunto
<a name="Expressions.ConditionExpressions.CheckingForContains"></a>

É possível verificar se há um elemento em um conjunto ou procurar uma substring em uma string usando a função `contains`. Se a expressão da condição for avaliada como verdadeira, a operação terá êxito. Caso contrário, haverá falha. 

O exemplo a seguir usará `contains` para excluir um produto somente se o Conjunto de strings `Color` tiver um elemento com um valor específico. 

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "contains(Color, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

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

```
{
    ":v_sub":{"S":"Red"}
}
```

### Verificar o tamanho do valor de um atributo
<a name="Expressions.ConditionExpressions.CheckingForSize"></a>

É possível verificar o tamanho do valor de um atributo usando a função `size`. Se a expressão da condição for avaliada como verdadeira, a operação terá êxito. Caso contrário, haverá falha. 

O exemplo a seguir usará `size` para excluir um produto somente se o tamanho do atributo binário `VideoClip` for maior que `64000` bytes. 

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "size(VideoClip) > :v_sub" \
    --expression-attribute-values file://expression-attribute-values.json
```

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

```
{
    ":v_sub":{"N":"64000"}
}
```

# Usar a vida útil (TTL) no DynamoDB
<a name="TTL"></a>

A vida útil (TTL) para DynamoDB é um método econômico para excluir itens que não são mais relevantes. A TTL permite definir um carimbo de data e hora de validade por item que indica quando um item não é mais necessário. O DynamoDB exclui automaticamente os itens expirados alguns dias após o vencimento, sem consumir o throughput de gravação. 

Para usar a TTL, primeiro habilite-a em uma tabela e, depois, defina um atributo específico para armazenar o carimbo de data e hora de vencimento da TTL. O carimbo de data/hora deve ser armazenado como um tipo de dados de [número](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes) no [formato de hora de época do Unix](https://en.wikipedia.org/wiki/Unix_time) na granularidade de segundos. Itens com um atributo TTL que não seja do tipo de número são ignorados pelo processo TTL. Sempre que um item é criado ou atualizado, é possível calcular o prazo de validade e salvá-lo no atributo TTL.

Itens com atributos TTL válidos e expirados podem ser excluídos pelo sistema a qualquer momento, normalmente alguns dias após a validade. Você ainda pode atualizar os itens expirados que estão pendentes de exclusão, incluindo alterar ou remover os atributos TTL. Ao atualizar um item expirado, recomendamos usar uma expressão de condição para garantir que o item não tenha sido excluído posteriormente. Use expressões de filtro para remover itens expirados dos resultados de [Scan](Scan.md#Scan.FilterExpression) e [Query](Query.FilterExpression.md).

Os itens excluídos funcionam de forma semelhante aos excluídos por meio de operações de exclusão típicas. Depois de excluídos, os itens entram no DynamoDB Streams como exclusões de serviços, em vez de exclusões de usuários, e são removidos dos índices secundários locais e globais, assim como outras operações de exclusão. 

Se estiver usando [Global Tables versão 2019.11.21 (atual)](GlobalTables.md) das tabelas globais e também usar o recurso TTL, o DynamoDB replicará as exclusões de TTL em todas as tabelas de réplica. A exclusão inicial de TTL não consome unidades de capacidade de gravação (WCU) na região onde a TTL expira. No entanto, a exclusão de TTL replicada para as tabelas de réplica consume uma unidade de capacidade de gravação replicada ao usar a capacidade provisionada ou a unidade de gravação replicada ao usar o modo de capacidade sob demanda, em cada uma das regiões de réplica, e serão aplicadas cobranças.

Para obter mais informações sobre TTL, consulte estes tópicos:

**Topics**
+ [Habilitar a vida útil (TTL) no DynamoDB](time-to-live-ttl-how-to.md)
+ [Como calcular a vida útil (TTL) no DynamoDB](time-to-live-ttl-before-you-start.md)
+ [Trabalhar com itens expirados e vida útil (TTL)](ttl-expired-items.md)

# Habilitar a vida útil (TTL) no DynamoDB
<a name="time-to-live-ttl-how-to"></a>

**nota**  
Para auxiliar na depuração e verificação da operação adequada do recurso TTL, os valores fornecidos para o item TTL são registrados em log em texto simples nos logs de diagnóstico do DynamoDB.

É possível habilitar a TTL no console do Amazon DynamoDB, na AWS Command Line Interface (AWS CLI) ou usando a [Referência da API do Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/) com qualquer um dos supostos SDKs da AWS. Demora cerca de uma hora para que a TTL seja habilitada em todas as partições.

## Habilitar a TTL do DynamoDB usando o console da AWS
<a name="time-to-live-ttl-how-to-enable-console"></a>

1. Faça login no Console de gerenciamento da AWS e abra o console do DynamoDB em [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. Escolha **Tables (Tabelas)** e selecione a tabela que você deseja modificar.

1. Na guia **Configurações adicionais**, na seção **Vida útil (TTL)**, selecione **Ativar** para habilitar a TTL.

1. Ao habilitar o TTL em uma tabela, o DynamoDB exige identificar um nome de atributo específico que o serviço procurará ao determinar se um item está qualificado para expiração. O nome do atributo TTL, mostrado abaixo, diferencia maiúsculas de minúsculas e deve corresponder ao atributo definido em suas operações de leitura e gravação. Uma incompatibilidade fará com que os itens expirados não sejam excluídos. Para renomear o atributo TTL, é necessário desabilitar a TTL e a reabilitar com o novo atributo daqui para frente. A TTL continuará processando as exclusões por cerca de trinta minutos depois de desabilitada. A TTL deve ser reconfigurada em tabelas restauradas.  
![\[Nome do atributo TTL com distinção entre maiúsculas e minúsculas que o DynamoDB usa para determinar a elegibilidade de um item para validade.\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/EnableTTL-Settings.png)

1. (Opcional) É possível realizar um teste simulando a data e a hora da validade e combinando alguns itens. Isso fornece uma lista de exemplos de itens e confirma que há itens com o nome do atributo TTL fornecido junto com o prazo de validade.

Depois de habilitar a TTL, o atributo TTL é marcado como **TTL** quando você visualiza itens no console do DynamoDB. Você pode visualizar a data e a hora em que um item expira posicionando o mouse sobre o atributo. 

## Habilitar a TTL do DynamoDB usando a API
<a name="time-to-live-ttl-how-to-enable-api"></a>

------
#### [ Python ]

É possível habilitar a TTL com código, usando a operação [UpdateTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/update_time_to_live.html).

```
import boto3


def enable_ttl(table_name, ttl_attribute_name):
    """
    Enables TTL on DynamoDB table for a given attribute name
        on success, returns a status code of 200
        on error, throws an exception

    :param table_name: Name of the DynamoDB table
    :param ttl_attribute_name: The name of the TTL attribute being provided to the table.
    """
    try:
        dynamodb = boto3.client('dynamodb')

        # Enable TTL on an existing DynamoDB table
        response = dynamodb.update_time_to_live(
            TableName=table_name,
            TimeToLiveSpecification={
                'Enabled': True,
                'AttributeName': ttl_attribute_name
            }
        )

        # In the returned response, check for a successful status code.
        if response['ResponseMetadata']['HTTPStatusCode'] == 200:
            print("TTL has been enabled successfully.")
        else:
            print(f"Failed to enable TTL, status code {response['ResponseMetadata']['HTTPStatusCode']}")
    except Exception as ex:
        print("Couldn't enable TTL in table %s. Here's why: %s" % (table_name, ex))
        raise


# your values
enable_ttl('your-table-name', 'expirationDate')
```

É possível confirmar se a TTL está habilitada usando a operação [DescribeTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/describe_time_to_live.html), que descreve o status da TTL em uma tabela. O status `TimeToLive` é `ENABLED` ou `DISABLED`.

```
# create a DynamoDB client
dynamodb = boto3.client('dynamodb')

# set the table name
table_name = 'YourTable'

# describe TTL
response = dynamodb.describe_time_to_live(TableName=table_name)
```

------
#### [ JavaScript ]

É possível habilitar a TTL com código, usando a operação [UpdateTimeToLiveCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-dynamodb/Class/UpdateTimeToLiveCommand/).

```
import { DynamoDBClient, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";

const enableTTL = async (tableName, ttlAttribute) => {

    const client = new DynamoDBClient({});

    const params = {
        TableName: tableName,
        TimeToLiveSpecification: {
            Enabled: true,
            AttributeName: ttlAttribute
        }
    };

    try {
        const response = await client.send(new UpdateTimeToLiveCommand(params));
        if (response.$metadata.httpStatusCode === 200) {
            console.log(`TTL enabled successfully for table ${tableName}, using attribute name ${ttlAttribute}.`);
        } else {
            console.log(`Failed to enable TTL for table ${tableName}, response object: ${response}`);
        }
        return response;
    } catch (e) {
        console.error(`Error enabling TTL: ${e}`);
        throw e;
    }
};

// call with your own values
enableTTL('ExampleTable', 'exampleTtlAttribute');
```

------

## Habilitar a vida útil usando a AWS CLI
<a name="time-to-live-ttl-how-to-enable-cli-sdk"></a>

1. Habilite o TTL na tabela `TTLExample`.

   ```
   aws dynamodb update-time-to-live --table-name TTLExample --time-to-live-specification "Enabled=true, AttributeName=ttl"
   ```

1. Descreva o TTL na tabela `TTLExample`.

   ```
   aws dynamodb describe-time-to-live --table-name TTLExample
   {
       "TimeToLiveDescription": {
           "AttributeName": "ttl",
           "TimeToLiveStatus": "ENABLED"
       }
   }
   ```

1. Para adicionar um item à tabela `TTLExample` com o conjunto de atributos de vida útil usando o shell BASH e a AWS CLI. 

   ```
   EXP=`date -d '+5 days' +%s`
   aws dynamodb put-item --table-name "TTLExample" --item '{"id": {"N": "1"}, "ttl": {"N": "'$EXP'"}}'
   ```

Este exemplo inicia na data atual e adiciona 5 dias a ela para criar uma data de expiração. Depois, ele converte a data de expiração em formato de hora epoch para finalmente adicionar um item à tabela "`TTLExample`". 

**nota**  
 Uma forma de definir os valores de expiração para a vida útil é calcular o número de segundos para adicionar o tempo de expiração. Por exemplo, 5 dias é igual a 432.000 segundos. No entanto, muitas vezes é preferível começar com uma data e trabalhar a partir desse ponto.

É muito simples obter a hora atual no formato de hora epoch, como nos seguintes exemplos.
+ Terminal Linux: `date +%s`
+ Python: `import time; int(time.time())`
+ Java: `System.currentTimeMillis() / 1000L`
+ JavaScript: : `Math.floor(Date.now() / 1000)`

## Habilitar a TTL do DynamoDB usando o CloudFormation
<a name="time-to-live-ttl-how-to-enable-cf"></a>

```
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  TTLExampleTable:
    Type: AWS::DynamoDB::Table
    Description: "A DynamoDB table with TTL Specification enabled"
    Properties:
      AttributeDefinitions:
        - AttributeName: "Album"
          AttributeType: "S"
        - AttributeName: "Artist"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "Album"
          KeyType: "HASH"
        - AttributeName: "Artist"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TimeToLiveSpecification:
        AttributeName: "TTLExampleAttribute"
        Enabled: true
```

Detalhes adicionais sobre o uso do TTL em seus modelos do CloudFormation podem ser encontrados [aqui](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-table-timetolivespecification.html).

# Como calcular a vida útil (TTL) no DynamoDB
<a name="time-to-live-ttl-before-you-start"></a>

Uma forma comum de implementar a TTL é definir um prazo de validade para os itens com base em quando eles foram criados ou atualizados pela última vez. Isso pode ser feito adicionando hora aos carimbos de data e hora `createdAt` e `updatedAt`. Por exemplo, a TTL para itens recém-criados pode ser definida como `createdAt` \$1 noventa dias. Quando o item é atualizado, a TTL pode ser recalculada para `updatedAt` \$1 noventa dias.

O prazo de validade calculado deve estar no formato de época, em segundos. Para ser considerada para validade e exclusão, a TTL não pode ter mais de cinco anos no passado. Se você usar qualquer outro formato, os processos TTL ignorarão o item. Se você definir o prazo de validade como algum momento no futuro em que quiser que o item expire, o item expira após esse horário. Por exemplo, digamos que você defina o prazo de validade como 1724241326 (que é segunda-feira, 21 de agosto de 2024, 11:55:26 (UTC)). O item expira após o horário especificado. Não há duração mínima de TTL. Você pode definir o prazo de validade para qualquer hora futura, como 5 minutos a partir da hora atual. No entanto, o DynamoDB normalmente exclui itens expirados dentro de 48 horas após o prazo de validade, não imediatamente quando o item expira.

**Topics**
+ [Criar um item e definir a vida útil](#time-to-live-ttl-before-you-start-create)
+ [Atualizar um item e atualizar a vida útil](#time-to-live-ttl-before-you-start-update)

## Criar um item e definir a vida útil
<a name="time-to-live-ttl-before-you-start-create"></a>

O exemplo a seguir demonstra como calcular o prazo de validade ao criar um item, usando `expireAt` como nome do atributo TTL. Uma declaração de atribuição exibe a hora atual como uma variável. No exemplo, o prazo de validade é calculado como noventa dias a partir do horário atual. A hora é então convertida no formato de época e salva como um tipo de dados inteiro no atributo TTL.

Os exemplos de código a seguir mostram como criar um item com TTL.

------
#### [ Java ]

**SDK para Java 2.x**  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Creates an item in a DynamoDB table with TTL attributes.
 * This class demonstrates how to add TTL expiration timestamps to DynamoDB items.
 */
public class CreateTTL {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <region>
            Where:
                tableName - The Amazon DynamoDB table being queried.
                primaryKey - The name of the primary key. Also known as the hash or partition key.
                sortKey - The name of the sort key. Also known as the range attribute.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String CREATION_DATE_ATTR = "creationDate";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String SUCCESS_MESSAGE = "%s PutItem operation with TTL successful.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs a CreateTTL instance with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public CreateTTL(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Constructs a CreateTTL with a default DynamoDB client.
     */
    public CreateTTL() {
        this.dynamoDbClient = null;
    }

    /**
     * Main method to demonstrate creating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new CreateTTL().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and create an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final CreateTTL createTTL = new CreateTTL(ddb);
            createTTL.createItemWithTTL(tableName, primaryKey, sortKey);
            return 0;
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * Creates an item in the specified table with TTL attributes.
     *
     * @param tableName The name of the table
     * @param primaryKeyValue The value for the primary key
     * @param sortKeyValue The value for the sort key
     * @return The response from the PutItem operation
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     */
    public PutItemResponse createItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long createDate = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = createDate + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        final Map<String, AttributeValue> itemMap = new HashMap<>();
        itemMap.put(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        itemMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());
        itemMap.put(
            CREATION_DATE_ATTR,
            AttributeValue.builder().n(String.valueOf(createDate)).build());
        itemMap.put(
            EXPIRE_AT_ATTR,
            AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final PutItemRequest request =
            PutItemRequest.builder().tableName(tableName).item(itemMap).build();

        try {
            final PutItemResponse response = dynamoDbClient.putItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  Consulte detalhes da API em [PutItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/PutItem) na *Referência da API AWS SDK for Java 2.x*. 

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  

```
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";

export function createDynamoDBItem(table_name, region, partition_key, sort_key) {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    // Get the current time in epoch second format
    const current_time = Math.floor(new Date().getTime() / 1000);

    // Calculate the expireAt time (90 days from now) in epoch second format
    const expire_at = Math.floor((new Date().getTime() + 90 * 24 * 60 * 60 * 1000) / 1000);

    // Create DynamoDB item
    const item = {
        'partitionKey': {'S': partition_key},
        'sortKey': {'S': sort_key},
        'createdAt': {'N': current_time.toString()},
        'expireAt': {'N': expire_at.toString()}
    };

    const putItemCommand = new PutItemCommand({
        TableName: table_name,
        Item: item,
        ProvisionedThroughput: {
            ReadCapacityUnits: 1,
            WriteCapacityUnits: 1,
        },
    });

    client.send(putItemCommand, function(err, data) {
        if (err) {
            console.log("Exception encountered when creating item %s, here's what happened: ", data, err);
            throw err;
        } else {
            console.log("Item created successfully: %s.", data);
            return data;
        }
    });
}

// Example usage (commented out for testing)
// createDynamoDBItem('your-table-name', 'us-east-1', 'your-partition-key-value', 'your-sort-key-value');
```
+  Consulte detalhes da API em [PutItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/PutItemCommand) na *Referência da API AWS SDK para JavaScript*. 

------
#### [ Python ]

**SDK para Python (Boto3).**  

```
from datetime import datetime, timedelta

import boto3


def create_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Creates a DynamoDB item with an attached expiry attribute.

    :param table_name: Table name for the boto3 resource to target when creating an item
    :param region: string representing the AWS region. Example: `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expiration time (90 days from now) in epoch second format
        expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        item = {
            "primaryKey": primary_key,
            "sortKey": sort_key,
            "creationDate": current_time,
            "expireAt": expiration_time,
        }
        response = table.put_item(Item=item)

        print("Item created successfully.")
        return response
    except Exception as e:
        print(f"Error creating item: {e}")
        raise e


# Use your own values
create_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  Consulte detalhes da API em [PutItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/PutItem) na *Referência da API do AWS SDK para Python (Boto3)*. 

------

## Atualizar um item e atualizar a vida útil
<a name="time-to-live-ttl-before-you-start-update"></a>

Este exemplo é uma continuação do exemplo da [seção anterior](#time-to-live-ttl-before-you-start-create). O prazo de validade poderá ser recalculado se o item for atualizado. O exemplo a seguir recalcula o carimbo de data e hora `expireAt` para ser noventa dias a partir da hora atual.

Os exemplos de código a seguir mostram como atualizar a TTL de um item.

------
#### [ Java ]

**SDK para Java 2.x**  
Atualize a TTL em um item do DynamoDB existente em uma tabela.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

    public UpdateItemResponse updateItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long currentTime = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = new HashMap<>();
        keyMap.put(PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        keyMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build());
        expressionAttributeValues.put(
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try {
            final UpdateItemResponse response = dynamoDbClient.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
```
+  Consulte detalhes da API em [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem) na *Referência da API AWS SDK for Java 2.x*. 

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItem = async (tableName, partitionKey, sortKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);
    const expireAt = Math.floor((Date.now() + 90 * 24 * 60 * 60 * 1000) / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            partitionKey: partitionKey,
            sortKey: sortKey
        }),
        UpdateExpression: "SET updatedAt = :c, expireAt = :e",
        ExpressionAttributeValues: marshall({
            ":c": currentTime,
            ":e": expireAt
        }),
    };

    try {
        const data = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(data.Attributes);
        console.log("Item updated successfully: %s", responseData);
        return responseData;
    } catch (err) {
        console.error("Error updating item:", err);
        throw err;
    }
}

// Example usage (commented out for testing)
// updateItem('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  Consulte detalhes da API em [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand) na *Referência da API AWS SDK para JavaScript*. 

------
#### [ Python ]

**SDK para Python (Boto3).**  

```
from datetime import datetime, timedelta

import boto3


def update_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Update an existing DynamoDB item with a TTL.
    :param table_name: Name of the DynamoDB table
    :param region: AWS Region of the table - example `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        # Create the DynamoDB resource.
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expireAt time (90 days from now) in epoch second format
        expire_at = int((datetime.now() + timedelta(days=90)).timestamp())

        table.update_item(
            Key={"partitionKey": primary_key, "sortKey": sort_key},
            UpdateExpression="set updatedAt=:c, expireAt=:e",
            ExpressionAttributeValues={":c": current_time, ":e": expire_at},
        )

        print("Item updated successfully.")
    except Exception as e:
        print(f"Error updating item: {e}")


# Replace with your own values
update_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  Consulte detalhes da API em [UpdateItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem) na *Referência da API AWS SDK para Python (Boto3)*. 

------

Os exemplos de TTL abordados nesta introdução demonstram um método que garante que somente os itens atualizados recentemente sejam mantidos em uma tabela. Os itens atualizados têm sua vida útil estendida, enquanto os itens não atualizados após a criação expiram e são excluídos sem nenhum custo, reduzindo o armazenamento e mantendo as tabelas limpas.

# Trabalhar com itens expirados e vida útil (TTL)
<a name="ttl-expired-items"></a>

Os itens expirados que estão pendentes de exclusão podem ser filtrados das operações de leitura e de gravação. Isso é útil em situações em que os dados expirados não são mais válidos e não devem ser usados. Se não forem filtrados, continuarão sendo exibidos nas operações de leitura e de gravação até serem excluídos pelo processo em segundo plano.

**nota**  
Esses itens ainda contam em relação aos custos de armazenamento e de leitura até serem excluídos.

As exclusões de TTL podem ser identificadas no DynamoDB Streams, mas somente na região em que a exclusão ocorreu. As exclusões de TTL que são replicadas em regiões da tabela global não podem ser identificadas nos fluxos do DynamoDB nas regiões nas quais a exclusão é replicada.

## Filtrar itens expirados das operações de leitura
<a name="ttl-expired-items-filter"></a>

Em relação a operações de leitura, como [Scan](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) e [Query](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html), uma expressão de filtro pode filtrar itens expirados que estão pendentes de exclusão. Conforme mostrado no trecho de código a seguir, a expressão de filtro pode filtrar itens em que a hora de TTL é igual ou menor que a hora atual. Por exemplo, o código do SDK para Python inclui uma declaração de atribuição que tem a hora atual como uma variável (`now`) e a converte em `int` para o formato de hora de época.

Os exemplos de código a seguir mostram como consultar itens com TTL.

------
#### [ Java ]

**SDK para Java 2.x**  
Use uma expressão filtrada na consulta para reunir os itens com TTL em uma tabela do DynamoDB por meio do AWS SDK for Java 2.x.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.Map;
import java.util.Optional;

        final QueryRequest request = QueryRequest.builder()
            .tableName(tableName)
            .keyConditionExpression(KEY_CONDITION_EXPRESSION)
            .filterExpression(FILTER_EXPRESSION)
            .expressionAttributeNames(expressionAttributeNames)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final QueryResponse response = ddb.query(request);
            System.out.println("Query successful. Found " + response.count() + " items that have not expired yet.");

            // Print each item
            response.items().forEach(item -> {
                System.out.println("Item: " + item);
            });

            return 0;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
```
+  Consulte detalhes da API em [Query](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/Query) na *Referência da API AWS SDK for Java 2.x*. 

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
Use uma expressão filtrada na consulta para reunir os itens com TTL em uma tabela do DynamoDB por meio do AWS SDK para JavaScript.  

```
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const queryFiltered = async (tableName, primaryKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);

    const params = {
        TableName: tableName,
        KeyConditionExpression: "#pk = :pk",
        FilterExpression: "#ea > :ea",
        ExpressionAttributeNames: {
            "#pk": "primaryKey",
            "#ea": "expireAt"
        },
        ExpressionAttributeValues: marshall({
            ":pk": primaryKey,
            ":ea": currentTime
        })
    };

    try {
        const { Items } = await client.send(new QueryCommand(params));
        Items.forEach(item => {
            console.log(unmarshall(item))
        });
        return Items;
    } catch (err) {
        console.error(`Error querying items: ${err}`);
        throw err;
    }
}

// Example usage (commented out for testing)
// queryFiltered('your-table-name', 'your-partition-key-value');
```
+  Consulte detalhes da API em [Query](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/QueryCommand) na *Referência da API AWS SDK para JavaScript*. 

------
#### [ Python ]

**SDK para Python (Boto3).**  
Use uma expressão filtrada na consulta para reunir os itens com TTL em uma tabela do DynamoDB por meio do AWS SDK para Python (Boto3).  

```
from datetime import datetime

import boto3


def query_dynamodb_items(table_name, partition_key):
    """

    :param table_name: Name of the DynamoDB table
    :param partition_key:
    :return:
    """
    try:
        # Initialize a DynamoDB resource
        dynamodb = boto3.resource("dynamodb", region_name="us-east-1")

        # Specify your table
        table = dynamodb.Table(table_name)

        # Get the current time in epoch format
        current_time = int(datetime.now().timestamp())

        # Perform the query operation with a filter expression to exclude expired items
        # response = table.query(
        #    KeyConditionExpression=boto3.dynamodb.conditions.Key('partitionKey').eq(partition_key),
        #    FilterExpression=boto3.dynamodb.conditions.Attr('expireAt').gt(current_time)
        # )
        response = table.query(
            KeyConditionExpression=dynamodb.conditions.Key("partitionKey").eq(partition_key),
            FilterExpression=dynamodb.conditions.Attr("expireAt").gt(current_time),
        )

        # Print the items that are not expired
        for item in response["Items"]:
            print(item)

    except Exception as e:
        print(f"Error querying items: {e}")


# Call the function with your values
query_dynamodb_items("Music", "your-partition-key-value")
```
+  Consulte detalhes da API em [Query](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/Query) na *Referência da API AWS SDK para Python (Boto3)*. 

------

## Gravar de modo condicional em itens expirados
<a name="ttl-expired-items-conditional-write"></a>

Uma expressão de condição pode ser usada para evitar gravações em itens expirados. O trecho de código abaixo é uma atualização condicional que confere se o prazo de validade é maior que o horário atual. Se verdadeiro, a operação de gravação continuará.

Os exemplos de código a seguir mostram como atualizar condicionalmente a TTL de um item.

------
#### [ Java ]

**SDK para Java 2.x**  
Atualize a TTL em um item do DynamoDB existente em uma tabela, com uma condição.  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

import java.util.Map;
import java.util.Optional;

/**
 * Updates an item in a DynamoDB table with TTL attributes using a conditional expression.
 * This class demonstrates how to conditionally update TTL expiration timestamps.
 */
public class UpdateTTLConditional {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <region>
            Where:
                tableName - The Amazon DynamoDB table being queried.
                primaryKey - The name of the primary key. Also known as the hash or partition key.
                sortKey - The name of the sort key. Also known as the range attribute.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String UPDATED_AT_ATTR = "updatedAt";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String UPDATE_EXPRESSION = "SET " + UPDATED_AT_ATTR + "=:c, " + EXPIRE_AT_ATTR + "=:e";
    private static final String CONDITION_EXPRESSION = "attribute_exists(" + PRIMARY_KEY_ATTR + ")";
    private static final String SUCCESS_MESSAGE = "%s UpdateItem operation with TTL successful.";
    private static final String CONDITION_FAILED_MESSAGE = "Condition check failed. Item does not exist.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs an UpdateTTLConditional with a default DynamoDB client.
     */
    public UpdateTTLConditional() {
        this.dynamoDbClient = null;
    }

    /**
     * Constructs an UpdateTTLConditional with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public UpdateTTLConditional(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Main method to demonstrate conditionally updating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new UpdateTTLConditional().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and conditionally update an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        // Get current time in epoch second format
        final long currentTime = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = Map.of(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKey).build(),
            SORT_KEY_ATTR, AttributeValue.builder().s(sortKey).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = Map.of(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build(),
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .conditionExpression(CONDITION_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final UpdateItemResponse response = ddb.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return 0;
        } catch (ConditionalCheckFailedException e) {
            System.err.println(CONDITION_FAILED_MESSAGE);
            throw e;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  Consulte detalhes da API em [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem) na *Referência da API AWS SDK for Java 2.x*. 

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
Atualize a TTL em um item do DynamoDB existente em uma tabela, com uma condição.  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItemConditional = async (tableName, partitionKey, sortKey, region = 'us-east-1', newAttribute = 'default-value') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            artist: partitionKey,
            album: sortKey
        }),
        UpdateExpression: "SET newAttribute = :newAttribute",
        ConditionExpression: "expireAt > :expiration",
        ExpressionAttributeValues: marshall({
            ':newAttribute': newAttribute,
            ':expiration': currentTime
        }),
        ReturnValues: "ALL_NEW"
    };

    try {
        const response = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(response.Attributes);
        console.log("Item updated successfully: ", responseData);
        return responseData;
    } catch (error) {
        if (error.name === "ConditionalCheckFailedException") {
            console.log("Condition check failed: Item's 'expireAt' is expired.");
        } else {
            console.error("Error updating item: ", error);
        }
        throw error;
    }
};

// Example usage (commented out for testing)
// updateItemConditional('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  Consulte detalhes da API em [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand) na *Referência da API AWS SDK para JavaScript*. 

------
#### [ Python ]

**SDK para Python (Boto3).**  
Atualize a TTL em um item do DynamoDB existente em uma tabela, com uma condição.  

```
from datetime import datetime, timedelta

import boto3
from botocore.exceptions import ClientError


def update_dynamodb_item_ttl(table_name, region, primary_key, sort_key, ttl_attribute):
    """
    Updates an existing record in a DynamoDB table with a new or updated TTL attribute.

    :param table_name: Name of the DynamoDB table
    :param region: AWS Region of the table - example `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :param ttl_attribute: name of the TTL attribute in the target DynamoDB table
    :return:
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Generate updated TTL in epoch second format
        updated_expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        # Define the update expression for adding/updating a new attribute
        update_expression = "SET newAttribute = :val1"

        # Define the condition expression for checking if 'expireAt' is not expired
        condition_expression = "expireAt > :val2"

        # Define the expression attribute values
        expression_attribute_values = {":val1": ttl_attribute, ":val2": updated_expiration_time}

        response = table.update_item(
            Key={"primaryKey": primary_key, "sortKey": sort_key},
            UpdateExpression=update_expression,
            ConditionExpression=condition_expression,
            ExpressionAttributeValues=expression_attribute_values,
        )

        print("Item updated successfully.")
        return response["ResponseMetadata"]["HTTPStatusCode"]  # Ideally a 200 OK
    except ClientError as e:
        if e.response["Error"]["Code"] == "ConditionalCheckFailedException":
            print("Condition check failed: Item's 'expireAt' is expired.")
        else:
            print(f"Error updating item: {e}")
    except Exception as e:
        print(f"Error updating item: {e}")


# replace with your values
update_dynamodb_item_ttl(
    "your-table-name",
    "us-east-1",
    "your-partition-key-value",
    "your-sort-key-value",
    "your-ttl-attribute-value",
)
```
+  Consulte detalhes da API em [UpdateItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem) na *Referência da API AWS SDK para Python (Boto3)*. 

------

## Identificar itens excluídos no DynamoDB Streams
<a name="ttl-expired-items-identifying"></a>

O registro de fluxos contém um campo de identidade do usuário `Records[<index>].userIdentity`. Os itens excluídos pelo processo do TTL têm os seguintes campos:

```
Records[<index>].userIdentity.type
"Service"

Records[<index>].userIdentity.principalId
"dynamodb.amazonaws.com"
```

O JSON a seguir mostra a parte relevante de um único registro de fluxos.

```
"Records": [ 
  { 
	... 
		"userIdentity": {
		"type": "Service", 
      	"principalId": "dynamodb.amazonaws.com" 
   	} 
   ... 
	} 
]
```

# Consultar tabelas no DynamoDB
<a name="Query"></a>

Você pode usar a operação de API `Query` no Amazon DynamoDB para encontrar itens com base nos valores de chave primária.

Você deve fornecer o nome do atributo de chave de partição e um único valor para esse atributo. A operação `Query` retorna todos os itens com esse valor de chave de partição. Opcionalmente, você pode fornecer um atributo de chave de classificação e usar um operador de comparação para refinar os resultados da pesquisa.

Para obter mais informações sobre como usar `Query`, como a sintaxe de solicitação, parâmetros de resposta e exemplos adicionais, acesse [Consulta](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) na *Referência da API do Amazon DynamoDB*.

**Topics**
+ [Principais expressões de condição para a operação de consulta no DynamoDB](Query.KeyConditionExpressions.md)
+ [Filtrar expressões para a operação de consulta no DynamoDB](Query.FilterExpression.md)
+ [Paginar os resultados de consultas à tabela no DynamoDB](Query.Pagination.md)
+ [Outros aspectos do trabalho com a operação de consulta no DynamoDB](Query.Other.md)

# Principais expressões de condição para a operação de consulta no DynamoDB
<a name="Query.KeyConditionExpressions"></a>

Você pode usar qualquer nome de atributo em uma expressão de condição principal, desde que o primeiro caractere seja `a-z` ou `A-Z` e o restante dos caracteres (a partir do segundo caractere, se houver) seja `a-z`, `A-Z` ou `0-9`. Além disso, o nome do atributo não deve ser uma palavra reservada do DynamoDB. (Para obter uma lista completa dessas palavras reservadas, consulte [Palavras reservadas no DynamoDB](ReservedWords.md).) Se um nome de atributo não atender a esses requisitos, defina um nome de atributo de expressão como um espaço reservado. Para obter mais informações, consulte [Nomes (aliases) de atributo de expressão no DynamoDB](Expressions.ExpressionAttributeNames.md).

Para itens com um determinado valor de chave de partição, o DynamoDB armazena esses itens juntos em ordem classificada por valor de chave de classificação. Em uma operação `Query`, o DynamoDB recupera os itens na ordem classificada e, em seguida, processa os itens usando `KeyConditionExpression` e qualquer `FilterExpression` que estiver presente. Somente então os resultados de `Query` são enviados de volta para o cliente.

Uma operação `Query` sempre retorna um conjunto de resultados. Se não forem encontrados itens correspondentes, o conjunto de resultados estará vazio.

`Query`Os resultados de são sempre classificados pelo valor de chave de classificação. Se o tipo de dados da chave de classificação for `Number`, os resultados serão retornados em ordem numérica. Caso contrário, os resultados serão retornados na ordem de bytes UTF-8. Por padrão, a ordem de classificação é crescente. Para reverter a ordem, defina o parâmetro `ScanIndexForward` como `false`.

Uma única operação `Query` pode recuperar um máximo de 1 MB de dados. Esse limite se aplica antes de qualquer expressão `FilterExpression` ou `ProjectionExpression` ser aplicada aos resultados. Se `LastEvaluatedKey` estiver presente na resposta e não for nula, você deverá paginar o conjunto de resultados (consulte [Paginar os resultados de consultas à tabela no DynamoDB](Query.Pagination.md)).

## Exemplos das principais expressões de condição
<a name="Query.KeyConditionExpressions-example"></a>

Para especificar os critérios de pesquisa, você deve usar uma *expressão de condição principal* – uma string que determina os itens a serem lidos da tabela ou índice.

Você deve especificar o nome e o valor da chave de partição como uma condição de igualdade. Não é possível usar um atributo que não seja de chave em uma expressão de condição de chave.

Opcionalmente, você pode fornecer uma segunda condição para a chave de classificação (se houver). A condição de chave de classificação deve usar um dos seguintes operadores de comparação:
+ `a = b` - verdadeiro se o atributo *a* for igual ao valor *b*
+ `a < b`: verdadeiro se *a* for menor que *b*
+ `a <= b`: verdadeiro se *a* for menor que ou igual a *b*
+ `a > b`: verdadeiro se *a* for maior que *b*
+ `a >= b`: verdadeiro se *a* for maior ou igual a *b*
+ `a BETWEEN b AND c` - verdadeiro se *a* for maior ou igual a *b*e menor ou igual a *c*.

A função a seguir também tem suporte:
+ `begins_with (a, substr)`- verdadeiro se o valor do atributo `a` começa com uma determinada substring.

Os seguintes exemplos da AWS Command Line Interface (AWS CLI) demonstram o uso das expressões de condição de chave. Essas expressões usam espaços reservados (como `:name` e `:sub`), em vez de valores reais. Para obter mais informações, consulte [Nomes (aliases) de atributo de expressão no DynamoDB](Expressions.ExpressionAttributeNames.md) e [Usar valores de atributos de expressão no DynamoDB](Expressions.ExpressionAttributeValues.md).

**Example**  
Consulte a tabela `Thread` para encontrar um `ForumName` específico (chave de partição). Todos os itens com esse valor de `ForumName` são lidos pela consulta, porque a chave de classificação (`Subject`) não está incluída na `KeyConditionExpression`.  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :name" \
    --expression-attribute-values  '{":name":{"S":"Amazon DynamoDB"}}'
```

**Example**  
Consulte a tabela `Thread` para encontrar um `ForumName` específico (chave de partição), mas, desta vez, retornar apenas os itens com um determinado `Subject` (chave de classificação).  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :name and Subject = :sub" \
    --expression-attribute-values  file://values.json
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":name":{"S":"Amazon DynamoDB"},
    ":sub":{"S":"DynamoDB Thread 1"}
}
```

**Example**  
Consulte a tabela `Reply` para encontrar um `Id` específico (chave de partição), mas retornar apenas os itens cuja `ReplyDateTime` (chave de classificação) começa com determinados caracteres.  

```
aws dynamodb query \
    --table-name Reply \
    --key-condition-expression "Id = :id and begins_with(ReplyDateTime, :dt)" \
    --expression-attribute-values  file://values.json
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":id":{"S":"Amazon DynamoDB#DynamoDB Thread 1"},
    ":dt":{"S":"2015-09"}
}
```

# Filtrar expressões para a operação de consulta no DynamoDB
<a name="Query.FilterExpression"></a>

Se você precisar refinar ainda mais os resultados de `Query`, existe a opção de utilizar uma expressão de filtro. Uma *expressão de filtro* determina quais itens dos resultados de `Query` devem ser retornados para você. Todos os outros resultados serão descartados.

Uma expressão de filtro é aplicada depois que uma operação `Query` é concluída, mas antes que os resultados sejam retornados. Portanto, uma operação `Query` consome a mesma quantidade de capacidade de leitura, independentemente de uma expressão de filtro estar presente.

Uma operação `Query` pode recuperar um máximo de 1 MB de dados. Esse limite se aplica antes de a expressão de filtro ser avaliada.

Uma expressão de filtro não pode conter atributos de chave de partição ou de chave de classificação. É necessário especificar esses atributos na expressão de condição principal, não na de filtro.

A sintaxe de uma expressão de filtro é semelhante à de uma expressão de condição de chave. As expressões de filtro podem usar os mesmos comparadores, funções e operadores lógicos que uma expressão de condição principal. Além disso, as expressões de filtro podem usar o operador diferente de (`<>`), bem como os operadores `OR`, `CONTAINS`, `IN`, `BEGINS_WITH`, `BETWEEN`, `EXISTS` e `SIZE`. Para obter mais informações, consulte [Principais expressões de condição para a operação de consulta no DynamoDB](Query.KeyConditionExpressions.md) e [Sintaxe para expressões de filtro e de condição](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Syntax).

**Example**  
O exemplo da AWS CLI a seguir consulta a tabela `Thread` para encontrar um `ForumName` (chave de partição) e um `Subject` (chave de classificação) específicos. Dos itens que são encontrados, somente os threads de discussão mais populares são retornados – em outras palavras, apenas os threads com mais de um determinado número de `Views`.  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :fn and Subject begins_with :sub" \
    --filter-expression "#v >= :num" \
    --expression-attribute-names '{"#v": "Views"}' \
    --expression-attribute-values file://values.json
```
Os argumentos de `--expression-attribute-values` são armazenados no arquivo `values.json`.  

```
{
    ":fn":{"S":"Amazon DynamoDB"},
    ":sub":{"S":"DynamoDB Thread 1"},
    ":num":{"N":"3"}
}
```
Observe que `Views` é uma palavra reservada no DynamoDB (consulte [Palavras reservadas no DynamoDB](ReservedWords.md)), portanto, este exemplo usa `#v` como um espaço reservado. Para obter mais informações, consulte [Nomes (aliases) de atributo de expressão no DynamoDB](Expressions.ExpressionAttributeNames.md).

**nota**  
Uma expressão de filtro remove itens do conjunto de resultados de `Query`. Se possível, evite usar `Query` onde você espera recuperar um grande número de itens, mas também precisa descartar a maioria desses itens.

# Paginar os resultados de consultas à tabela no DynamoDB
<a name="Query.Pagination"></a>

O DynamoDB *pagina* os resultados das operações `Query`. Com a paginação, os resultados de `Query` são divididos em "páginas" de dados com 1 MB de tamanho (ou menos). Uma aplicação pode processar a primeira página de resultados e, em seguida, a segunda página, e assim por diante.

Uma única operação `Query` retorna apenas um conjunto de resultados que estão dentro do limite de tamanho de 1 MB. Para determinar se há mais resultados e para recuperá-los em uma página por vez, os aplicativos devem fazer o seguinte: 

1. Examine o resultado de `Query` de baixo nível:
   + Se o resultado contiver um elemento `LastEvaluatedKey` e ele não for nulo, prossiga para a etapa 2.
   + Se *não* houver um `LastEvaluatedKey` no resultado, não haverá mais itens a serem recuperados.

1. Crie uma `Query` com a mesma `KeyConditionExpression`. No entanto, desta vez, use o valor de `LastEvaluatedKey` da etapa 1 como o parâmetro `ExclusiveStartKey` na nova solicitação de `Query`.

1. Execute a nova solicitação de `Query`.

1. Vá para a etapa 1.

Em outras palavras, o valor `LastEvaluatedKey` de uma resposta de `Query` deve ser usado como `ExclusiveStartKey` da próxima solicitação de `Query`. Se não houver um elemento `LastEvaluatedKey` em uma resposta de `Query`, então, você recuperou a página de resultados final. Se `LastEvaluatedKey` não está vazio, isso não necessariamente significa que há mais dados no conjunto de resultados. A única maneira de saber quando você atingiu o final do conjunto de resultados é quando `LastEvaluatedKey` estiver vazio.

Você pode usar a AWS CLI para visualizar esse comportamento. A AWS CLI envia repetidamente solicitações `Query` de baixo nível ao DynamoDB até que `LastEvaluatedKey` não esteja mais presente nos resultados. Considere o seguinte exemplo da AWS CLI que recupera títulos de filmes de um determinado ano.

```
aws dynamodb query --table-name Movies \
    --projection-expression "title" \
    --key-condition-expression "#y = :yyyy" \
    --expression-attribute-names '{"#y":"year"}' \
    --expression-attribute-values '{":yyyy":{"N":"1993"}}' \
    --page-size 5 \
    --debug
```

Normalmente, a AWS CLI lida com a paginação automaticamente. No entanto, neste exemplo, o parâmetro AWS CLI da `--page-size` limita o número de itens por página. O parâmetro de `--debug` imprime as informações de baixo nível sobre solicitações e respostas.

Se você executar o exemplo, a primeira resposta do DynamoDB será semelhante a esta.

```
2017-07-07 11:13:15,603 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":5,"Items":[{"title":{"S":"A Bronx Tale"}},
{"title":{"S":"A Perfect World"}},{"title":{"S":"Addams Family Values"}},
{"title":{"S":"Alive"}},{"title":{"S":"Benny & Joon"}}],
"LastEvaluatedKey":{"year":{"N":"1993"},"title":{"S":"Benny & Joon"}},
"ScannedCount":5}'
```

O `LastEvaluatedKey` na resposta indica que nem todos os itens foram recuperados. A AWS CLI emite outra solicitação de `Query` para o DynamoDB. Essa solicitação e o padrão de resposta continuam, até a resposta final.

```
2017-07-07 11:13:16,291 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":1,"Items":[{"title":{"S":"What\'s Eating Gilbert Grape"}}],"ScannedCount":1}'
```

A ausência de `LastEvaluatedKey` indica que não há mais itens a serem recuperados.

**nota**  
Os AWS SDKs lidam com as respostas de baixo nível do DynamoDB (incluindo a presença ou a ausência de `LastEvaluatedKey`) e fornecem várias abstrações para paginar os resultados de `Query` Por exemplo, a interface do documento SDK para Java fornece o suporte a `java.util.Iterator` para que você possa abordar um resultado de cada vez.  
Para obter exemplos de código em várias linguagens de programação, consulte o [Guia de conceitos básicos do Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/) e a documentação do AWS SDK para sua linguagem.

Você também pode reduzir o tamanho da página limitando o número de itens no conjunto de resultados, com o parâmetro `Limit` da operação `Query`.

Para obter mais informações sobre como realizar consultas com o DynamoDB, veja [Consultar tabelas no DynamoDB](Query.md).

# Outros aspectos do trabalho com a operação de consulta no DynamoDB
<a name="Query.Other"></a>

Esta seção aborda aspectos adicionais da operação de consulta do DynamoDB, incluindo a limitação do tamanho dos resultados, a contagem de itens varridos versus retornados, o monitoramento do consumo da capacidade de leitura e o controle da consistência de leitura.

## Limitar o número de itens no conjunto de resultados
<a name="Query.Limit"></a>

Com a operação `Query`, você pode limitar o número de itens lidos. Para fazer isso, defina o parâmetro `Limit` com o número máximo de itens que você deseja.

Por exemplo, suponha que você execute a operação `Query` em uma tabela, com um valor de `Limit` igual a `6` e sem uma expressão de filtro. O resultado de `Query` contém os primeiros seis itens da tabela que correspondem à expressão de condição da chave da solicitação.

Agora suponha que você adicione uma expressão de filtro à operação `Query`. Nesse caso, o DynamoDB lê até seis itens e retorna somente aqueles que correspondem à expressão do filtro. O resultado final de `Query` contém seis itens ou menos, mesmo que mais itens tivessem correspondido à expressão do filtro se o DynamoDB continuasse lendo mais itens.

## Contar os itens nos resultados
<a name="Query.Count"></a>

Além dos itens que correspondem aos seus critérios, a resposta de `Query` contém os elementos a seguir:
+ `ScannedCount`: o número de itens que corresponderam à expressão de condição principal, *antes* que uma expressão de filtro (se alguma) fosse aplicada.
+ `Count`: o número de itens que permaneceram *depois* que uma expressão de filtro (se alguma) foi aplicada.

**nota**  
Se você não usar uma expressão de filtro, `ScannedCount` e `Count` terão o mesmo valor.

Se o tamanho do conjunto de resultados de `Query` for maior que 1 MB, `ScannedCount` e `Count` representarão apenas uma contagem parcial do total de itens. Você precisa executar várias operações `Query` para recuperar todos os resultados (consulte [Paginar os resultados de consultas à tabela no DynamoDB](Query.Pagination.md)).

Cada resposta de `Query` contém os valores de `ScannedCount` e de `Count` dos itens que foram processados pela solicitação de `Query` específica. Para obter os totais gerais de todas as solicitações de `Query`, você pode manter um total em execução de `ScannedCount` e `Count`.

## Unidades de capacidade consumidas por consulta
<a name="Query.CapacityUnits"></a>

Você pode usar `Query` em qualquer tabela ou índice secundário, desde que forneça o nome do atributo da chave de partição e um valor único para esse atributo. `Query` retorna todos os itens com esse valor de chave de partição. Opcionalmente, você pode fornecer um atributo de chave de classificação e usar um operador de comparação para refinar os resultados da pesquisa. `Query` As operações de API consomem unidades de capacidade de leitura da seguinte forma:


****  

| Se você executar uma operação `Query`... | O DynamoDB consumirá unidades de capacidade de leitura de... | 
| --- | --- | 
| Tabela | A capacidade de leitura provisionada da tabela. | 
| Índice secundário global | A capacidade de leitura provisionada do índice. | 
| Índice secundário local | A capacidade de leitura provisionada da tabela-base. | 

Por padrão, uma operação `Query` não retorna quaisquer dados sobre quanta capacidade de leitura ela consome. Entretanto, você pode especificar o parâmetro `ReturnConsumedCapacity` em uma solicitação de `Query` para obter essas informações. A seguir estão as configurações válidas de `ReturnConsumedCapacity`:
+ `NONE`: nenhum dado de capacidade consumida é retornado. (Esse é o padrão.)
+ `TOTAL`: a resposta inclui o número agregado de unidades de capacidade de leitura consumidas.
+ `INDEXES`: a resposta mostra o número agregado de unidades de capacidade de leitura consumidas, junto com a capacidade consumida para cada tabela e índice acessados.

O DynamoDB calcula o número de unidades de capacidade de leitura consumidas com base na quantidade e no tamanho desses itens, não na quantidade de dados exibidos para uma aplicação. Por esse motivo, o número de unidades de capacidade consumidas será o mesmo, independentemente de você solicitar todos os atributos (o comportamento padrão) ou apenas alguns deles (usando uma expressão de projeção). O número também é o mesmo, independentemente de você usar ou não uma expressão de filtro. `Query` consome uma unidade de capacidade mínima de leitura para realizar uma leitura altamente consistente por segundo ou duas leituras finais consistentes por segundo para um item de até 4 KB. Se você precisar ler um item com mais de 4 KB, o DynamoDB precisará de unidades de solicitação de leitura adicionais. Tabelas vazias e tabelas muito grandes que têm uma quantidade esparsa de chaves de partição podem ter algumas RCUs adicionais cobradas além da quantidade de dados consultados. Isso cobre o custo de atender à solicitação `Query`, mesmo que não existam dados.

## Consistência de leitura para consulta
<a name="Query.ReadConsistency"></a>

Uma operação `Query` executa leituras finais consistentes, por padrão. Isso significa que os resultados de `Query` talvez não reflitam as alterações causadas pelas operações `PutItem` ou `UpdateItem` concluídas recentemente. Para obter mais informações, consulte [Consistência de leitura do DynamoDB](HowItWorks.ReadConsistency.md).

Se você precisar de leituras fortemente consistentes, defina o parâmetro `ConsistentRead` como `true` na solicitação de `Query`.

# Verificar tabelas no DynamoDB
<a name="Scan"></a>

Uma operação `Scan` no Amazon DynamoDB lê cada item de uma tabela ou de um índice secundário. Por padrão, uma operação `Scan` retorna todos os atributos de dados de cada item na tabela ou índice. Você pode usar o parâmetro `ProjectionExpression` para que a operação `Scan` retorne apenas alguns dos atributos, em vez de todos eles.

`Scan` sempre retorna um conjunto de resultados. Se não forem encontrados itens correspondentes, o conjunto de resultados estará vazio.

Uma única solicitação de `Scan` pode recuperar um máximo de 1 MB de dados. Opcionalmente, o DynamoDB pode aplicar uma expressão de filtro a esses dados, restringindo os resultados antes que eles sejam retornados ao usuário.

**Topics**
+ [Expressões de filtro para verificação](#Scan.FilterExpression)
+ [Limitar o número de itens no conjunto de resultados](#Scan.Limit)
+ [Paginar resultados](#Scan.Pagination)
+ [Contar os itens nos resultados](#Scan.Count)
+ [Unidades de capacidade consumidas por verificação](#Scan.CapacityUnits)
+ [Consistência de leitura para verificação](#Scan.ReadConsistency)
+ [Verificar em paralelo](#Scan.ParallelScan)

## Expressões de filtro para verificação
<a name="Scan.FilterExpression"></a>

Se você precisar refinar ainda mais os resultados de `Scan`, existe a opção de utilizar uma expressão de filtro. Uma *expressão de filtro* determina quais itens dos resultados de `Scan` devem ser retornados para você. Todos os outros resultados serão descartados.

Uma expressão de filtro é aplicada depois que uma operação `Scan` é concluída, mas antes que os resultados sejam retornados. Portanto, uma operação `Scan` consome a mesma quantidade de capacidade de leitura, independentemente de uma expressão de filtro estar presente.

Uma operação `Scan` pode recuperar um máximo de 1 MB de dados. Esse limite se aplica antes de a expressão de filtro ser avaliada.

Com `Scan`, você pode especificar quaisquer atributos em uma expressão de filtro, incluindo atributos de chave de partição ou de chave de classificação.

A sintaxe de uma expressão de filtro é idêntica à de uma expressão de condição. As expressões de filtro podem usar os mesmos comparadores, funções e operadores lógicos que uma expressão de condição. Consulte [Expressões de condição e filtro, operadores e funções no DynamoDB](Expressions.OperatorsAndFunctions.md) para obter mais informações sobre operadores lógicos.

**Example**  
O exemplo da AWS Command Line Interface (AWS CLI) a seguir verifica a tabela `Thread` e retorna apenas os itens que foram publicados pela última vez por um usuário específico.  

```
aws dynamodb scan \
     --table-name Thread \
     --filter-expression "LastPostedBy = :name" \
     --expression-attribute-values '{":name":{"S":"User A"}}'
```

## Limitar o número de itens no conjunto de resultados
<a name="Scan.Limit"></a>

A operação `Scan` permite que você limite o número de itens retornados no resultado. Para fazer isso, defina o parâmetro `Limit` como o número máximo de itens que você deseja que a operação `Scan` retorne, antes da avaliação da expressão de filtro.

Por exemplo, suponha que você execute a operação `Scan` em uma tabela, com um valor de `Limit` igual a `6` e sem uma expressão de filtro. O resultado `Scan` contém os primeiros seis itens da tabela.

Agora suponha que você adicione uma expressão de filtro à operação `Scan`. Nesse caso, o DynamoDB aplicará a expressão de filtro aos seis itens que foram retornados e descarta os que não correspondem. O resultado final de `Scan` contém 6 itens ou menos, dependendo do número de itens que foram filtrados.

## Paginar resultados
<a name="Scan.Pagination"></a>

O DynamoDB *pagina* os resultados das operações `Scan`. Com a paginação, os resultados de `Scan` são divididos em "páginas" de dados com 1 MB de tamanho (ou menos). Uma aplicação pode processar a primeira página de resultados e, em seguida, a segunda página, e assim por diante.

Uma única operação `Scan` retorna apenas um conjunto de resultados que estão dentro do limite de tamanho de 1 MB. 

Para determinar se há mais resultados e para recuperá-los em uma página por vez, as aplicações devem fazer o seguinte:

1. Examine o resultado de `Scan` de baixo nível:
   + Se o resultado contiver um elemento `LastEvaluatedKey`, prossiga para a etapa 2.
   + Se *não* houver um `LastEvaluatedKey` no resultado, não haverá mais itens a serem recuperados.

1. Construa a nova solicitação de `Scan` com os mesmos parâmetros da anterior. No entanto, desta vez, use o valor de `LastEvaluatedKey` da etapa 1 como o parâmetro `ExclusiveStartKey` na nova solicitação de `Scan`.

1. Execute a nova solicitação de `Scan`.

1. Vá para a etapa 1.

Em outras palavras, o valor `LastEvaluatedKey` de uma resposta de `Scan` deve ser usado como `ExclusiveStartKey` da próxima solicitação de `Scan`. Se não houver um elemento `LastEvaluatedKey` em uma resposta de `Scan`, você terá recuperado a página de resultados final. (A ausência de `LastEvaluatedKey` é a única forma de você saber que chegou ao fim do conjunto de resultados.)

Você pode usar a AWS CLI para visualizar esse comportamento. A AWS CLI envia repetidamente solicitações `Scan` de baixo nível ao DynamoDB até que `LastEvaluatedKey` não esteja mais presente nos resultados. Considere o seguinte exemplo da AWS CLI que verifica toda a tabela `Movies`, mas retorna apenas os filmes de um determinado gênero.

```
aws dynamodb scan \
    --table-name Movies \
    --projection-expression "title" \
    --filter-expression 'contains(info.genres,:gen)' \
    --expression-attribute-values '{":gen":{"S":"Sci-Fi"}}' \
    --page-size 100  \
    --debug
```

Normalmente, a AWS CLI lida com a paginação automaticamente. No entanto, neste exemplo, o parâmetro AWS CLI da `--page-size` limita o número de itens por página. O parâmetro de `--debug` imprime as informações de baixo nível sobre solicitações e respostas.

**nota**  
Os resultados da paginação também serão diferentes com base nos parâmetros de entrada que você passar.   
O uso de `aws dynamodb scan --table-name Prices --max-items 1` retorna `NextToken`
O uso de `aws dynamodb scan --table-name Prices --limit 1` retorna `LastEvaluatedKey`.
Também esteja ciente de que usar`--starting-token`, em especial, requer o valor `NextToken`. 

Se você executar o exemplo, a primeira resposta do DynamoDB será semelhante ao seguinte:

```
2017-07-07 12:19:14,389 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":7,"Items":[{"title":{"S":"Monster on the Campus"}},{"title":{"S":"+1"}},
{"title":{"S":"100 Degrees Below Zero"}},{"title":{"S":"About Time"}},{"title":{"S":"After Earth"}},
{"title":{"S":"Age of Dinosaurs"}},{"title":{"S":"Cloudy with a Chance of Meatballs 2"}}],
"LastEvaluatedKey":{"year":{"N":"2013"},"title":{"S":"Curse of Chucky"}},"ScannedCount":100}'
```

O `LastEvaluatedKey` na resposta indica que nem todos os itens foram recuperados. A AWS CLI emite outra solicitação de `Scan` para o DynamoDB. Essa solicitação e o padrão de resposta continuam, até a resposta final.

```
2017-07-07 12:19:17,830 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":1,"Items":[{"title":{"S":"WarGames"}}],"ScannedCount":6}'
```

A ausência de `LastEvaluatedKey` indica que não há mais itens a serem recuperados.

**nota**  
Os AWS SDKs lidam com as respostas de baixo nível do DynamoDB (incluindo a presença ou a ausência de `LastEvaluatedKey`) e fornecem várias abstrações para paginar os resultados de `Scan` Por exemplo, a interface do documento SDK para Java fornece o suporte a `java.util.Iterator` para que você possa abordar um resultado de cada vez.  
Para obter exemplos de código em várias linguagens de programação, consulte o [Guia de conceitos básicos do Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/) e a documentação do AWS SDK para sua linguagem.

## Contar os itens nos resultados
<a name="Scan.Count"></a>

Além dos itens que correspondem aos seus critérios, a resposta de `Scan` contém os elementos a seguir:
+ `ScannedCount`: o número de itens avaliados antes de qualquer `ScanFilter` ser aplicado. Um valor alto de `ScannedCount` com poucos ou nenhum resultado de `Count` indica uma operação `Scan` ineficiente. Se você não tiver usado um filtro na solicitação, `ScannedCount` será o mesmo que `Count`. 
+ `Count`: o número de itens que permaneceram *depois* que uma expressão de filtro (se alguma) foi aplicada.

**nota**  
Se você não usar uma expressão de filtro, `ScannedCount` e `Count` terão o mesmo valor.

Se o tamanho do conjunto de resultados de `Scan` for maior que 1 MB, `ScannedCount` e `Count` representarão apenas uma contagem parcial do total de itens. Você precisa executar várias operações `Scan` para recuperar todos os resultados (consulte [Paginar resultados](#Scan.Pagination)).

Cada resposta de `Scan` contém os valores de `ScannedCount` e de `Count` dos itens que foram processados pela solicitação de `Scan` específica. Para obter os totais gerais de todas as solicitações de `Scan`, você pode manter um total em execução de `ScannedCount` e de `Count`.

## Unidades de capacidade consumidas por verificação
<a name="Scan.CapacityUnits"></a>

Você pode executar `Scan` em qualquer tabela ou índice secundário. As operações `Scan` consomem unidades de capacidade de leitura da seguinte forma.


****  

| Se você executar uma operação `Scan`... | O DynamoDB consumirá unidades de capacidade de leitura de... | 
| --- | --- | 
| Tabela | A capacidade de leitura provisionada da tabela. | 
| Índice secundário global | A capacidade de leitura provisionada do índice. | 
| Índice secundário local | A capacidade de leitura provisionada da tabela-base. | 

**nota**  
Atualmente, o acesso entre contas para operações de verificação de índice secundário não é aceito em [políticas baseadas em recursos](access-control-resource-based.md).

Por padrão, uma operação `Scan` não retorna quaisquer dados sobre quanta capacidade de leitura ela consome. Entretanto, você pode especificar o parâmetro `ReturnConsumedCapacity` em uma solicitação de `Scan` para obter essas informações. A seguir estão as configurações válidas de `ReturnConsumedCapacity`:
+ `NONE`: nenhum dado de capacidade consumida é retornado. (Esse é o padrão.)
+ `TOTAL`: a resposta inclui o número agregado de unidades de capacidade de leitura consumidas.
+ `INDEXES`: a resposta mostra o número agregado de unidades de capacidade de leitura consumidas, junto com a capacidade consumida para cada tabela e índice acessados.

O DynamoDB calcula o número de unidades de capacidade de leitura consumidas com base na quantidade e no tamanho desses itens, não na quantidade de dados exibidos para uma aplicação. Por esse motivo, o número de unidades de capacidade consumidas será o mesmo, independentemente de você solicitar todos os atributos (o comportamento padrão) ou apenas alguns deles (usando uma expressão de projeção). O número também é o mesmo, independentemente de você usar ou não uma expressão de filtro. `Scan` consome uma unidade de capacidade mínima de leitura para realizar uma leitura altamente consistente por segundo ou duas leituras finais consistentes por segundo para um item de até 4 KB. Se você precisar ler um item com mais de 4 KB, o DynamoDB precisará de unidades de solicitação de leitura adicionais. Tabelas vazias e tabelas muito grandes que têm uma quantidade esparsa de chaves de partição podem ter algumas RCUs adicionais cobradas além da quantidade de dados verificados. Isso cobre o custo de atender à solicitação `Scan`, mesmo que não existam dados.

## Consistência de leitura para verificação
<a name="Scan.ReadConsistency"></a>

Uma operação `Scan` executa leituras finais consistentes, por padrão. Isso significa que os resultados de `Scan` talvez não reflitam as alterações causadas pelas operações `PutItem` ou `UpdateItem` concluídas recentemente. Para obter mais informações, consulte [Consistência de leitura do DynamoDB](HowItWorks.ReadConsistency.md).

Se você precisar de leituras altamente consistentes, como a hora em que a operação `Scan` começa, defina o parâmetro `ConsistentRead` como `true` na solicitação de `Scan`. Isso garante que todas as operações de gravação que foram concluídas antes de `Scan` ter começado sejam incluídas na resposta de `Scan`. 

Pode ser útil configurar `ConsistentRead` como `true` no backup da tabela ou em cenários de replicação, juntamente com o [Amazon DynamoDB Streams](./Streams.html). Primeiro, você usa `Scan` com `ConsistentRead` definida como true para obter uma cópia consistente dos dados na tabela. Durante a operação `Scan`, o DynamoDB Streams registra qualquer atividade de gravação adicional que ocorra na tabela. Após a conclusão de `Scan`, você pode aplicar a atividade de gravação do fluxo à tabela.

**nota**  
Uma operação `Scan` com `ConsistentRead` definida como `true` consome duas vezes mais unidades de capacidade de leitura, em comparação com deixar `ConsistentRead` com seu valor padrão (`false`).

## Verificar em paralelo
<a name="Scan.ParallelScan"></a>

Por padrão, a operação `Scan` processa os dados sequencialmente. O Amazon DynamoDB retorna os dados para a aplicação em incrementos de 1 MB, e uma aplicação realiza operações `Scan` adicionais para recuperar os próximos 1 MB de dados. 

Quanto maior a tabela ou índice que está sendo verificado, mais tempo a operação `Scan` levará para ser concluída. Além disso, uma operação `Scan` sequencial talvez nem sempre consiga utilizar totalmente a capacidade de throughput de leitura provisionada: embora o DynamoDB distribua os dados de uma tabela grande entre várias partições físicas, uma operação `Scan` pode ler apenas uma partição de cada vez. Por esse motivo, o throughput de uma operação `Scan` é restrita pelo throughput máximo de uma única partição.

Para solucionar esses problemas, a operação `Scan` pode dividir logicamente uma tabela ou um índice secundário em vários *segmentos*, com vários operadores da aplicação verificando os segmentos em paralelo. Cada operador pode ser um thread (em linguagens de programação que aceitam multithreading) ou um processo do sistema operacional. Para executar uma verificação em paralelo, cada operador emite sua própria solicitação de `Scan` com os seguintes parâmetros:
+ `Segment`: um segmento a ser verificado por um determinado operador. Cada operador deve usar um valor diferente para `Segment`.
+ `TotalSegments`: o número total de segmentos para a verificação em paralelo. Esse valor deve ser o mesmo que o número de operadores que sua aplicação usará.

O diagrama a seguir mostra como uma aplicação multithread executa uma operação `Scan` em paralelo com três níveis de paralelismo:

![\[Uma aplicação multithread que executa uma verificação paralela, dividindo uma tabela em três segmentos.\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/ParallelScan.png)




Neste diagrama, a aplicação gera três threads e atribui um número a cada thread. (Segmentos são baseados em zero, portanto, o primeiro número é sempre 0.) Cada thread emite uma solicitação de `Scan`, configurando `Segment` como seu número designado e `TotalSegments` como 3. Cada thread verifica seu segmento designado, recuperando 1 MB de dados por vez, e retorna os dados para o thread principal da aplicação.

O DynamoDB atribui itens a *segmentos* aplicando uma função hash à chave de partição de cada item. Para determinado valor `TotalSegments`, todos os itens com a mesma chave de partição são sempre atribuídos ao mesmo `Segment`. Isso significa que, em uma tabela em que o *Item 1*, o *Item 2* e o *Item 3* compartilham `pk="account#123"` (mas têm chaves de classificação diferentes), esses itens serão processados pelo mesmo trabalhador, independentemente dos valores da chave de classificação ou do tamanho da *coleção de itens*.

Como a atribuição de *segmentos* é baseada somente no hash da chave de partição, os segmentos podem ser distribuídos de forma desigual. Alguns segmentos podem não conter itens, enquanto outros podem conter muitas chaves de partição com grandes coleções de itens. Como resultado, aumentar o número total de segmentos não garante uma performance mais rápida de verificação, especialmente quando as chaves de partição não são distribuídas de modo uniforme no espaço de teclas.

Os valores para `Segment` e `TotalSegments` aplicam-se a solicitações de `Scan` individuais, e você pode usar valores diferentes a qualquer momento. Talvez você precise experimentar com esses valores, e o número de operadores que usa, até que seu aplicativo atinja a melhor performance.

**nota**  
Uma operação Scan em paralelo com um grande número de operadores pode facilmente consumir todo o throughput provisionado da tabela ou índice que está sendo verificado. É melhor evitar tais verificações, se a tabela ou índice também incorrer em uso intensivo de atividades de leitura ou de gravação de outras aplicações.  
Para controlar a quantidade de dados retornados por solicitação, use o parâmetro `Limit`. Isso pode ajudar a evitar situações em que um operador consome todo o throughput provisionado, às custas de todos os outros operadores.

# PartiQL: uma linguagem de consultas compatível com SQL para o Amazon DynamoDB
<a name="ql-reference"></a>

O Amazon DynamoDB oferece suporte a [PartiQL](https://partiql.org/), uma linguagem de consultas compatível com SQL, para selecionar, inserir, atualizar e excluir dados no Amazon DynamoDB. Usando PartiQL, você pode interagir facilmente com tabelas do DynamoDB e executar consultas ad hoc usando o Console de gerenciamento da AWS, o NoSQL Workbench, a AWS Command Line Interfacee as APIs do DynamoDB para PartiQL.

As operações PartiQL fornecem as mesmas disponibilidade, latência e performance que as outras operações de plano de dados do DynamoDB.

As seções a seguir descrevem a implementação de PartiQL do DynamoDB.

**Topics**
+ [O que é PartiQL?](#ql-reference.what-is)
+ [PartiQL no Amazon DynamoDB](#ql-reference.what-is)
+ [Introdução](ql-gettingstarted.md)
+ [Tipos de dados](ql-reference.data-types.md)
+ [Declarações](ql-reference.statements.md)
+ [Funções](ql-functions.md)
+ [Operadores](ql-operators.md)
+ [Transações](ql-reference.multiplestatements.transactions.md)
+ [Operações em lote](ql-reference.multiplestatements.batching.md)
+ [Políticas do IAM](ql-iam.md)

## O que é PartiQL?
<a name="ql-reference.what-is"></a>

A linguagem *PartiQL* garante acesso de consultas compatíveis com SQL em vários armazenamentos de dados que contêm dados estruturados, dados semiestruturados e dados aninhados. Ela é amplamente utilizada na Amazon e agora está disponível como parte de muitos serviços da AWS, incluindo o DynamoDB.

Para obter a especificação da PartiQL e um tutorial sobre a linguagem de consulta principal, consulte a [Documentação da PartiQL](https://partiql.org/docs.html).

**nota**  
O Amazon DynamoDB oferece suporte a um *subconjunto* da linguagem de consultas [PartiQL](https://partiql.org/).
O Amazon DynamoDB não é compatível com o formato de dados [Amazon Ion](http://amzn.github.io/ion-docs/) nem com liderais do Amazon Ion.

## PartiQL no Amazon DynamoDB
<a name="ql-reference.what-is"></a>

Para executar consultas PartiQL no DynamoDB, você pode usar:
+ O console do DynamoDB
+ O NoSQL Workbench
+ A AWS Command Line Interface (AWS CLI)
+ As APIs do DynamoDB

Para obter informações sobre como usar esses métodos para acessar o DynamoDB, consulte [Acesso ao DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html).

# Conceitos básicos de PartiQL para DynamoDB
<a name="ql-gettingstarted"></a>

Esta seção descreve como usar PartiQL para DynamoDB via console do Amazon DynamoDB, AWS Command Line Interface (AWS CLI) e APIs do DynamoDB.

Nos exemplos a seguir, a tabela do DynamoDB definida no tutorial [Conceitos básicos do DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html) é um pré-requisito.

Para obter informações sobre como usar o console do DynamoDB, a AWS Command Line Interface ou as APIs do DynamoDB para acessar o DynamoDB, consulte [Acesso ao DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html).

Para [baixar](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html) e usar o [NoSQL Workbench](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html) para criar instruções em [PartiQL para DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html), escolha **PartiQL Operations** (Operações PartiQL) no canto superior direito do [Criador de operações](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.querybuilder.operationbuilder.html) do NoSQL Workbench para DynamoDB.

------
#### [ Console ]

![\[Interface do Editor PartiQL que mostra o resultado da execução da operação de consulta na tabela Music.\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/partiqlgettingstarted.png)


1. Faça login no Console de gerenciamento da AWS e abra o console do DynamoDB em [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. No painel de navegação, no lado esquerdo do console, selecione **PartiQL editor** (Editor de PartiQL).

1. Escolha a tabela **Music**.

1. Escolha **Query table** (Consultar tabela). Essa ação gera uma consulta que não resultará em uma varredura de tabela completa.

1. Substitua `partitionKeyValue` pelo valor da string `Acme Band`. Substitua `sortKeyValue` pelo valor da string `Happy Day`.

1. Selecione o botão **Run (Executar)**. 

1. Você pode visualizar os resultados da consulta escolhendo a opção **Table view** (Visualização da tabela ou **JSON view** (Visualização de JSON). 

------
#### [ NoSQL workbench ]

![\[Interface do NoSQL Workbench. Ela mostra uma declaração PartiQL SELECT que você pode executar na tabela Music.\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/images/workbench/partiql.single.png)


1. Escolha **PartiQL statement** (Instrução PartiQL).

1. Insira a seguinte [instrução SELECT](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html) PartiQL 

   ```
   SELECT *                                         
   FROM Music  
   WHERE Artist=? and SongTitle=?
   ```

1. Para especificar um valor para os parâmetros `Artist` e `SongTitle`:

   1. Escolha **Optional request parameters** (Parâmetros de solicitação opcionais).

   1. Escolha **Add new parameters** (Adicionar novos parâmetros).

   1. Escolha o tipo de atributo **string** e o valor `Acme Band`.

   1. Repita as etapas b e c e escolha o tipo **string** e o valor `PartiQL Rocks`. 

1. Se desejar gerar código, escolha **Generate code** (Gerar código).

   Selecione a linguagem desejada nas guias exibidas. Agora você pode copiar esse código e usá-lo na sua aplicação.

1. Se desejar que a operação seja executada imediatamente, escolha **Run** (Executar).

------
#### [ AWS CLI ]

1. Crie um item na tabela `Music` usando a instrução PartiQL INSERT. 

   ```
   aws dynamodb execute-statement --statement "INSERT INTO Music  \
   					    VALUE  \
   					    {'Artist':'Acme Band','SongTitle':'PartiQL Rocks'}"
   ```

1. Recupere um item da tabela Music usando a instrução PartiQL SELECT.

   ```
   aws dynamodb execute-statement --statement "SELECT * FROM Music   \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. Atualize um item na tabela `Music` usando a instrução PartiQL UPDATE.

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardsWon=1  \
                                               SET AwardDetail={'Grammys':[2020, 2018]}  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Adicione um valor de lista para um item na tabela `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Remova um valor de lista para um item na tabela `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               REMOVE AwardDetail.Grammys[2]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Adicione um novo membro de mapa para um item na tabela `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.BillBoard=[2020]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Adicione um novo atributo de conjunto de strings para um item na tabela `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =<<'member1', 'member2'>>  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   Atualize um atributo de conjunto de strings para um item na tabela `Music`. 

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =set_add(BandMembers, <<'newmember'>>)  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. Exclua um item da tabela `Music` usando a instrução PartiQL DELETE.

   ```
   aws dynamodb execute-statement --statement "DELETE  FROM Music  \
       WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

------
#### [ Java ]

```
import java.util.ArrayList;
import java.util.List;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import software.amazon.dynamodb.AmazonDynamoDB;
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import software.amazon.dynamodb.model.AttributeValue;
import software.amazon.dynamodb.model.ConditionalCheckFailedException;
import software.amazon.dynamodb.model.ExecuteStatementRequest;
import software.amazon.dynamodb.model.ExecuteStatementResult;
import software.amazon.dynamodb.model.InternalServerErrorException;
import software.amazon.dynamodb.model.ItemCollectionSizeLimitExceededException;
import software.amazon.dynamodb.model.ProvisionedThroughputExceededException;
import software.amazon.dynamodb.model.RequestLimitExceededException;
import software.amazon.dynamodb.model.ResourceNotFoundException;
import software.amazon.dynamodb.model.TransactionConflictException;

public class DynamoDBPartiQGettingStarted {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-1");

        try {
            // Create ExecuteStatementRequest
            ExecuteStatementRequest executeStatementRequest = new ExecuteStatementRequest();
            List<AttributeValue> parameters= getPartiQLParameters();

            //Create an item in the Music table using the INSERT PartiQL statement
            processResults(executeStatementRequest(dynamoDB, "INSERT INTO Music value {'Artist':?,'SongTitle':?}", parameters));

            //Retrieve an item from the Music table using the SELECT PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "SELECT * FROM Music  where Artist=? and SongTitle=?", parameters));

            //Update an item in the Music table using the UPDATE PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist=? and SongTitle=?", parameters));

            //Add a list value for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  where Artist=? and SongTitle=?", parameters));

            //Remove a list value for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music REMOVE AwardDetail.Grammys[2]   where Artist=? and SongTitle=?", parameters));

            //Add a new map member for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music set AwardDetail.BillBoard=[2020] where Artist=? and SongTitle=?", parameters));

            //Add a new string set attribute for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET BandMembers =<<'member1', 'member2'>> where Artist=? and SongTitle=?", parameters));

            //update a string set attribute for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET BandMembers =set_add(BandMembers, <<'newmember'>>) where Artist=? and SongTitle=?", parameters));

            //Retrieve an item from the Music table using the SELECT PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "SELECT * FROM Music  where Artist=? and SongTitle=?", parameters));

            //delete an item from the Music Table
            processResults(executeStatementRequest(dynamoDB, "DELETE  FROM Music  where Artist=? and SongTitle=?", parameters));
        } catch (Exception e) {
            handleExecuteStatementErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {
        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static List<AttributeValue> getPartiQLParameters() {
        List<AttributeValue> parameters = new ArrayList<AttributeValue>();
        parameters.add(new AttributeValue("Acme Band"));
        parameters.add(new AttributeValue("PartiQL Rocks"));
        return parameters;
    }

    private static ExecuteStatementResult executeStatementRequest(AmazonDynamoDB client, String statement, List<AttributeValue> parameters ) {
        ExecuteStatementRequest request = new ExecuteStatementRequest();
        request.setStatement(statement);
        request.setParameters(parameters);
        return client.executeStatement(request);
    }

    private static void processResults(ExecuteStatementResult executeStatementResult) {
        System.out.println("ExecuteStatement successful: "+ executeStatementResult.toString());

    }

    // Handles errors during ExecuteStatement execution. Use recommendations in error messages below to add error handling specific to
    // your application use-case.
    private static void handleExecuteStatementErrors(Exception exception) {
        try {
            throw exception;
        } catch (ConditionalCheckFailedException ccfe) {
            System.out.println("Condition check specified in the operation failed, review and update the condition " +
                                       "check before retrying. Error: " + ccfe.getErrorMessage());
        } catch (TransactionConflictException tce) {
            System.out.println("Operation was rejected because there is an ongoing transaction for the item, generally " +
                                       "safe to retry with exponential back-off. Error: " + tce.getErrorMessage());
        } catch (ItemCollectionSizeLimitExceededException icslee) {
            System.out.println("An item collection is too large, you\'re using Local Secondary Index and exceeded " +
                                       "size limit of items per partition key. Consider using Global Secondary Index instead. Error: " + icslee.getErrorMessage());
        } catch (Exception e) {
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " +
                                       "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                                       "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " +
                                       ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " +
                                       "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                                       "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                                       "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                                       "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

## Usar instruções parametrizadas
<a name="ql-gettingstarted.parameterized"></a>

Em vez de incorporar valores diretamente em uma string de instrução PartiQL, é possível usar espaços reservados com ponto de interrogação (`?`) e fornecer os valores separadamente no campo `Parameters`. Cada `?` é substituído pelo valor do parâmetro correspondente, na ordem em que é fornecido.

Usar instruções parametrizadas é uma prática recomendada porque separa a estrutura da instrução dos valores dos dados, facilitando a leitura e a reutilização das instruções. Isso também evita a necessidade de formatar e escapar manualmente dos valores dos atributos na string da instrução.

É possível usar instruções parametrizadas nas operações `ExecuteStatement`, `BatchExecuteStatement` e `ExecuteTransaction`.

Os exemplos a seguir recuperam um item da tabela `Music` usando valores parametrizados para a chave de partição e a chave de classificação.

------
#### [ AWS CLI parameterized ]

```
aws dynamodb execute-statement \
    --statement "SELECT * FROM \"Music\" WHERE Artist=? AND SongTitle=?" \
    --parameters '[{"S": "Acme Band"}, {"S": "PartiQL Rocks"}]'
```

------
#### [ Java parameterized ]

```
List<AttributeValue> parameters = new ArrayList<>();
parameters.add(new AttributeValue("Acme Band"));
parameters.add(new AttributeValue("PartiQL Rocks"));

ExecuteStatementRequest request = new ExecuteStatementRequest()
    .withStatement("SELECT * FROM Music WHERE Artist=? AND SongTitle=?")
    .withParameters(parameters);

ExecuteStatementResult result = dynamoDB.executeStatement(request);
```

------
#### [ Python parameterized ]

```
response = dynamodb_client.execute_statement(
    Statement="SELECT * FROM Music WHERE Artist=? AND SongTitle=?",
    Parameters=[
        {'S': 'Acme Band'},
        {'S': 'PartiQL Rocks'}
    ]
)
```

------

**nota**  
O exemplo Java na seção de introdução anterior sempre usa instruções parametrizadas. O método `getPartiQLParameters()` cria a lista de parâmetros e cada instrução usa `?` como espaço reservado em vez de valores em linha.

# Tipos de dados de PartiQL para DynamoDB
<a name="ql-reference.data-types"></a>

A tabela a seguir lista os tipos de dados que você pode usar com a linguagem PartiQL para DynamoDB.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/amazondynamodb/latest/developerguide/ql-reference.data-types.html)

## Exemplos
<a name="ql-reference.data-types"></a>

A instrução a seguir demonstra como inserir os seguintes tipos de dados: `String`, `Number`, `Map`, `List`, `Number Set` e `String Set`.

```
INSERT INTO TypesTable value {'primarykey':'1', 
'NumberType':1,
'MapType' : {'entryname1': 'value', 'entryname2': 4}, 
'ListType': [1,'stringval'], 
'NumberSetType':<<1,34,32,4.5>>, 
'StringSetType':<<'stringval','stringval2'>>
}
```

A instrução a seguir demonstra como inserir novos elementos nos tipos `Map`, `List`, `Number Set` e `String Set` e alterar o valor de um tipo `Number`.

```
UPDATE TypesTable 
SET NumberType=NumberType + 100 
SET MapType.NewMapEntry=[2020, 'stringvalue', 2.4]
SET ListType = LIST_APPEND(ListType, [4, <<'string1', 'string2'>>])
SET NumberSetType= SET_ADD(NumberSetType, <<345, 48.4>>)
SET StringSetType = SET_ADD(StringSetType, <<'stringsetvalue1', 'stringsetvalue2'>>)
WHERE primarykey='1'
```

A instrução a seguir demonstra como remover elementos dos tipos `Map`, `List`, `Number Set` e `String Set` e alterar o valor de um tipo `Number`.

```
UPDATE TypesTable 
SET NumberType=NumberType - 1
REMOVE ListType[1]
REMOVE MapType.NewMapEntry
SET NumberSetType = SET_DELETE( NumberSetType, <<345>>)
SET StringSetType = SET_DELETE( StringSetType, <<'stringsetvalue1'>>)
WHERE primarykey='1'
```

Para obter mais informações, consulte [Tipos de dados do DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes).

# Instruções em PartiQL para DynamoDB
<a name="ql-reference.statements"></a>

O Amazon DynamoDB oferece suporte às instruções PartiQL a seguir.

**nota**  
O DynamoDB não oferece suporte a todas as instruções PartiQL.  
Esta referência apresenta a sintaxe básica e fornece exemplos de uso de instruções PartiQL que você deve executar manualmente usando o AWS CLI ou APIs.

*Linguagem de manipulação de dados* (DML) é o conjunto de instruções PartiQL que você usa para gerenciar dados em tabelas do DynamoDB. Você usa instruções DML para adicionar, modificar ou excluir dados em uma tabela.

As seguintes instruções de linguagem DML e consultas são aceitas:
+ [Instruções Select em PartiQL para DynamoDB](ql-reference.select.md)
+ [Instruções Update em PartiQL para DynamoDB](ql-reference.update.md)
+ [Instruções Insert em PartiQL para DynamoDB](ql-reference.insert.md)
+ [Instruções Delete em PartiQL para DynamoDB](ql-reference.delete.md)

[Executar transações com PartiQL para DynamoDB](ql-reference.multiplestatements.transactions.md) e [Executar operações em lote com PartiQL para DynamoDB](ql-reference.multiplestatements.batching.md) também são compatíveis com a linguagem PartiQL para DynamoDB.

# Instruções Select em PartiQL para DynamoDB
<a name="ql-reference.select"></a>

Use a instrução `SELECT` para recuperar dados de uma tabela no Amazon DynamoDB.

O uso da declaração `SELECT` poderá gerar uma verificação completa da tabela se uma condição de igualdade ou IN com uma chave de partição não for fornecida na cláusula WHERE. Uma operação de verificação examina todos os itens com os valores solicitados e pode usar o throughput provisionado para uma tabela ou índice grande em uma única operação. 

Se desejar evitar a verificação completa da tabela em PartiQL, você pode:
+ Criar suas instruções `SELECT` para não resultar em verificações completas de tabela, certificando-se de que a [condição da cláusula WHERE](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html#ql-reference.select.parameters) seja configurada de acordo.
+ Desativar verificações completas de tabela usando a política do IAM especificada em [Exemplo: permitir instruções Select e negar instruções de verificação de tabela completa em PartiQL para DynamoDB](ql-iam.md#access-policy-ql-iam-example6), conforme descrito no Guia do desenvolvedor do DynamoDB.

Para obter mais informações, consulte [Melhores práticas para consulta e verificação de dados](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-query-scan.html) no Guia do desenvolvedor do DynamoDB.

**Topics**
+ [Sintaxe](#ql-reference.select.syntax)
+ [Parâmetros](#ql-reference.select.parameters)
+ [Exemplos](#ql-reference.select.examples)

## Sintaxe
<a name="ql-reference.select.syntax"></a>

```
SELECT expression  [, ...] 
FROM table[.index]
[ WHERE condition ] [ [ORDER BY key [DESC|ASC] , ...]
```

## Parâmetros
<a name="ql-reference.select.parameters"></a>

***expressão***  
(Obrigatório) Uma projeção formada a partir do curinga `*` ou uma lista de projeção de um ou mais nomes de atributos ou caminhos de documentos do conjunto de resultados. Uma expressão pode consistir em chamadas para [Usar funções PartiQL com o DynamoDB](ql-functions.md) ou campos que são modificados por [Operadores aritméticos, comparativos e lógicos de PartiQL para DynamoDB](ql-operators.md).

***table***  
(Obrigatório) O nome da tabela a ser consultada.

***Índice do***  
(Opcional) O nome do índice para consultar.  
É necessário adicionar aspas duplas ao nome da tabela e ao nome do índice ao consultar um índice.  

```
SELECT * 
FROM "TableName"."IndexName"
```

***Condição***  
(Opcional) Os critérios de seleção para a consulta.  
Para garantir que uma instrução `SELECT` não resulte em uma verificação completa da tabela, a condição da cláusula `WHERE` deverá especificar uma chave de partição. Use o operador de igualdade ou IN.  
Por exemplo, se você tiver uma tabela `Orders` com uma partição `OrderID` e outros atributos não chave, incluindo um `Address`, as seguintes instruções não resultarão em uma varredura completa da tabela:  

```
SELECT * 
FROM "Orders" 
WHERE OrderID = 100

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 and Address='some address'

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 or OrderID = 200

SELECT * 
FROM "Orders" 
WHERE OrderID IN [100, 300, 234]
```
As instruções `SELECT` a seguir, no entanto, resultarão em uma varredura completa da tabela:  

```
SELECT * 
FROM "Orders" 
WHERE OrderID > 1

SELECT * 
FROM "Orders" 
WHERE Address='some address'

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 OR Address='some address'
```

***key***  
(Opcional) Uma chave de hash ou uma chave de classificação a ser usada para ordenar os resultados retornados. A ordem padrão é crescente (`ASC`). Especifique `DESC` se desejar que os resultados sejam retornados em ordem decrescente.

**nota**  
Se você omitir a cláusula `WHERE`, todos os itens da tabela serão recuperados.

## Exemplos
<a name="ql-reference.select.examples"></a>

A consulta a seguir retorna um item, se houver, da tabela `Orders` mediante a especificação da chave de partição `OrderID` e o uso do operador de igualdade.

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID = 1
```

A consulta a seguir retorna todos os itens na tabela `Orders` que têm uma chave de partição específica, `OrderID`, valores usando o operador OR.

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID = 1 OR OrderID = 2
```

A consulta a seguir retorna todos os itens na tabela `Orders` que têm uma chave de partição específica, `OrderID`, valores usando o operador IN. Os resultados retornados estão em ordem decrescente, com base no valor de atributo de chave `OrderID`.

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID IN [1, 2, 3] ORDER BY OrderID DESC
```

A consulta a seguir mostra uma varredura de tabela completa que retorna todos os itens da tabela `Orders`que têm uma `Total` maior que 500, onde `Total` é um atributo não chave.

```
SELECT OrderID, Total 
FROM "Orders"
WHERE Total > 500
```

A consulta a seguir mostra uma varredura de tabela completa que retorna todos os itens da tabela `Orders` em um intervalo de ordem `Total` específico, usando o operador IN e um atributo não chave `Total`.

```
SELECT OrderID, Total 
FROM "Orders"
WHERE Total IN [500, 600]
```

A consulta a seguir mostra uma varredura de tabela completa que retorna todos os itens da tabela `Orders` em um intervalo de ordem `Total` específico, usando o operador BETWEEN e um atributo não chave `Total`.

```
SELECT OrderID, Total 
FROM "Orders" 
WHERE Total BETWEEN 500 AND 600
```

A consulta a seguir retorna a primeira data em que um dispositivo firestick foi usado para observar mediante a especificação da chave de partição `CustomerID` e da chave de classificação `MovieID` na condição da cláusula WHERE e usando caminhos de documento na cláusula SELECT.

```
SELECT Devices.FireStick.DateWatched[0] 
FROM WatchList 
WHERE CustomerID= 'C1' AND MovieID= 'M1'
```

A consulta a seguir mostra uma verificação de tabela completa que retorna a lista de itens em que um dispositivo firestick foi usado pela primeira vez após 24/12/19 usando caminhos de documento na condição da cláusula WHERE.

```
SELECT Devices 
FROM WatchList 
WHERE Devices.FireStick.DateWatched[0] >= '12/24/19'
```

# Instruções Update em PartiQL para DynamoDB
<a name="ql-reference.update"></a>

Use a instrução `UPDATE` para modificar o valor de um ou mais atributos em um item em uma tabela do Amazon DynamoDB. 

**nota**  
Você só pode atualizar um item de cada vez; não é possível emitir uma única instrução PartiQL do DynamoDB para atualizar vários itens. Para obter informações sobre como atualizar vários itens, consulte [Executar transações com PartiQL para DynamoDB](ql-reference.multiplestatements.transactions.md) ou [Executar operações em lote com PartiQL para DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [Sintaxe](#ql-reference.update.syntax)
+ [Parâmetros](#ql-reference.update.parameters)
+ [Valor de retorno](#ql-reference.update.return)
+ [Exemplos](#ql-reference.update.examples)

## Sintaxe
<a name="ql-reference.update.syntax"></a>

```
UPDATE  table  
[SET | REMOVE]  path  [=  data] […]
WHERE condition [RETURNING returnvalues]
<returnvalues>  ::= [ALL OLD | MODIFIED OLD | ALL NEW | MODIFIED NEW] *
```

## Parâmetros
<a name="ql-reference.update.parameters"></a>

***table***  
(Obrigatório) A tabela que contém os dados a serem modificados.

***caminho***  
(Obrigatório) Um nome de atributo ou caminho de documento a ser criado ou modificado.

***data***  
(Obrigatório) Um valor de atributo ou o resultado de uma operação.  
As operações com suporte a serem usadas com SET:  
+ LIST\$1APPEND: adiciona um valor a um tipo de lista.
+ SET\$1ADD: adiciona um valor a um conjunto de números ou strings.
+ SET\$1DELETE: remove um valor de um conjunto de números ou strings.

***Condição***  
(Obrigatório) Os critérios de seleção para o item a ser modificado. Essa condição deve ser resolvida em um único valor de chave primária.

***returnvalues***  
(Opcional) Use `returnvalues` se desejar obter os atributos de item como eles aparecem antes ou depois de serem atualizados. Os valores válidos são:   
+ `ALL OLD *`: retorna todos os atributos do item como eles apareciam antes da operação de atualização.
+ `MODIFIED OLD *`: retorna somente os atributos atualizados como eles apareciam antes da operação de atualização.
+ `ALL NEW *`: retorna todos os atributos do item como eles aparecem após a operação de atualização.
+ `MODIFIED NEW *` : retorna somente os atributos atualizados como eles aparecem após a operação `UpdateItem`.

## Valor de retorno
<a name="ql-reference.update.return"></a>

Esta instrução não retornará um valor a menos que o parâmetro `returnvalues` seja especificado.

**nota**  
Se a cláusula WHERE da instrução UPDATE não for avaliada como true para nenhum item na tabela do DynamoDB, `ConditionalCheckFailedException` será retornado.

## Exemplos
<a name="ql-reference.update.examples"></a>

Atualiza um valor de atributo em um item existente. Se o atributo não existir, ele será criado.

A consulta a seguir atualiza um item na tabela `"Music"` adicionando um atributo do tipo Number (`AwardsWon`) e um atributo do tipo Map (`AwardDetail`).

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

Você pode adicionar `RETURNING ALL OLD *` para retornar os atributos como eles apareceram antes da operação `Update`.

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
RETURNING ALL OLD *
```

Isso retorna o seguinte:

```
{
    "Items": [
        {
            "Artist": {
                "S": "Acme Band"
            },
            "SongTitle": {
                "S": "PartiQL Rocks"
            }
        }
    ]
}
```

Você pode adicionar `RETURNING ALL NEW *` para retornar os atributos como eles apareceram depois da operação `Update`.

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
RETURNING ALL NEW *
```

Isso retorna o seguinte:

```
{
    "Items": [
        {
            "AwardDetail": {
                "M": {
                    "Grammys": {
                        "L": [
                            {
                                "N": "2020"
                            },
                            {
                                "N": "2018"
                            }
                        ]
                    }
                }
            },
            "AwardsWon": {
                "N": "1"
            }
        }
    ]
}
```

A consulta a seguir atualiza um item na tabela `"Music"` anexando-o a uma lista `AwardDetail.Grammys`.

```
UPDATE "Music" 
SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

A consulta a seguir atualiza um item na tabela `"Music"` removendo-o de uma lista `AwardDetail.Grammys`.

```
UPDATE "Music" 
REMOVE AwardDetail.Grammys[2]   
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

A consulta a seguir atualiza um item na tabela `"Music"` adicionando `BillBoard` ao mapa `AwardDetail`.

```
UPDATE "Music" 
SET AwardDetail.BillBoard=[2020] 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

A consulta a seguir atualiza um item na tabela `"Music"` adicionando o atributo de conjunto de strings `BandMembers`.

```
UPDATE "Music" 
SET BandMembers =<<'member1', 'member2'>> 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

A consulta a seguir atualiza um item na tabela `"Music"` adicionando `newbandmember` ao conjunto de strings `BandMembers`.

```
UPDATE "Music" 
SET BandMembers =set_add(BandMembers, <<'newbandmember'>>) 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

# Instruções Delete em PartiQL para DynamoDB
<a name="ql-reference.delete"></a>

Use a instrução `DELETE` para excluir um item existente da tabela do Amazon DynamoDB.

**nota**  
É possível excluir apenas um item de cada vez. Você não pode emitir uma única instrução PartiQL do DynamoDB para excluir vários itens. Para obter informações sobre como excluir vários itens, consulte [Executar transações com PartiQL para DynamoDB](ql-reference.multiplestatements.transactions.md) ou [Executar operações em lote com PartiQL para DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [Sintaxe](#ql-reference.delete.syntax)
+ [Parâmetros](#ql-reference.delete.parameters)
+ [Valor de retorno](#ql-reference.delete.return)
+ [Exemplos](#ql-reference.delete.examples)

## Sintaxe
<a name="ql-reference.delete.syntax"></a>

```
DELETE FROM table 
 WHERE condition [RETURNING returnvalues]
 <returnvalues>  ::= ALL OLD *
```

## Parâmetros
<a name="ql-reference.delete.parameters"></a>

***table***  
(Obrigatório) A tabela do DynamoDB que contém o item a ser excluído.

***Condição***  
(Obrigatório) Os critérios de seleção para o item a ser excluído; essa condição deve ser resolvida para um único valor de chave primária.

***returnvalues***  
(Opcional) Use `returnvalues` se desejar obter os atributos do item como eles apareciam antes de ser excluídos. Os valores válidos são:   
+ `ALL OLD *`: o conteúdo do item antigo é retornado.

## Valor de retorno
<a name="ql-reference.delete.return"></a>

Esta instrução não retornará um valor a menos que o parâmetro `returnvalues` seja especificado.

**nota**  
Se a tabela do DynamoDB não tiver nenhum item com a mesma chave primária que a do item para o qual a instrução DELETE foi emitida, SUCESS será retornado com 0 itens excluídos. Se a tabela tiver um item com a mesma chave primária, mas a condição na cláusula WHERE da instrução DELETE for avaliada como false, `ConditionalCheckFailedException` será retornado.

## Exemplos
<a name="ql-reference.delete.examples"></a>

A consulta a seguir exclui um item da tabela `"Music"`.

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks'
```

Você pode adicionar o parâmetro `RETURNING ALL OLD *` para retornar os dados que foram excluídos.

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks' RETURNING ALL OLD *
```

A instrução `Delete` agora retorna o seguinte:

```
{
    "Items": [
        {
            "Artist": {
                "S": "Acme Band"
            },
            "SongTitle": {
                "S": "PartiQL Rocks"
            }
        }
    ]
}
```

# Instruções Insert em PartiQL para DynamoDB
<a name="ql-reference.insert"></a>

Use a instrução `INSERT` para adicionar um item a uma tabela no Amazon DynamoDB.

**nota**  
Você só pode inserir um item de cada vez; não é possível emitir uma única instrução PartiQL do DynamoDB para inserir vários itens. Para obter informações sobre como inserir vários itens, consulte [Executar transações com PartiQL para DynamoDB](ql-reference.multiplestatements.transactions.md) ou [Executar operações em lote com PartiQL para DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [Sintaxe](#ql-reference.insert.syntax)
+ [Parâmetros](#ql-reference.insert.parameters)
+ [Valor de retorno](#ql-reference.insert.return)
+ [Exemplos](#ql-reference.insert.examples)

## Sintaxe
<a name="ql-reference.insert.syntax"></a>

Insira um único item.

```
INSERT INTO table VALUE item
```

## Parâmetros
<a name="ql-reference.insert.parameters"></a>

***table***  
(Obrigatório) A tabela na qual você deseja inserir os dados. A tabela já deve existir.

***item***  
(Obrigatório) Um item válido do DynamoDB representado como uma [tupla PartiQL](https://partiql.org/docs.html). Você só deve especificar *um* item, e cada nome de atributo no item diferencia maiúsculas e minúsculas e pode ser indicado com aspas *simples* (`'...'`) na linguagem PartiQL.  
Os valores de string também são denotados com aspas *simples* (`'...'`) em PartiQL.

## Valor de retorno
<a name="ql-reference.insert.return"></a>

Esta instrução não retorna nenhum valor.

**nota**  
Se a tabela do DynamoDB já tiver um item com a mesma chave primária da chave primária do item que está sendo inserido, `DuplicateItemException` será retornado.

## Exemplos
<a name="ql-reference.insert.examples"></a>

```
INSERT INTO "Music" value {'Artist' : 'Acme Band','SongTitle' : 'PartiQL Rocks'}
```

# Usar funções PartiQL com o DynamoDB
<a name="ql-functions"></a>

A linguagem PartiQL no Amazon DynamoDB é compatível com as seguintes variantes integradas de funções padrão SQL.

**nota**  
As funções SQL que não fazem parte desta lista não são aceitas no DynamoDB.

## Funções agregadas
<a name="ql-functions.aggregate"></a>
+ [Usar a função SIZE com PartiQL para Amazon DynamoDB](ql-functions.size.md)

## Funções condicionais
<a name="ql-functions.conditional"></a>
+ [Usar a função EXISTS com PartiQL para DynamoDB](ql-functions.exists.md)
+ [Usar a função ATTRIBUTE\$1TYPE com PartiQL para DynamoDB](ql-functions.attribute_type.md)
+ [Usar a função BEGINS\$1WITH com PartiQL para DynamoDB](ql-functions.beginswith.md)
+ [Usar a função CONTAINS com PartiQL para DynamoDB](ql-functions.contains.md)
+ [Usar a função MISSING com PartiQL para DynamoDB](ql-functions.missing.md)

# Usar a função EXISTS com PartiQL para DynamoDB
<a name="ql-functions.exists"></a>

Você pode usar EXISTS para executar a mesma função que `ConditionCheck` na API [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems). A função EXISTS só pode ser usada em transações.

Sendo fornecido um valor, a função retornará `TRUE` se o valor for uma coleção não vazia. Caso contrário, gera `FALSE`.

**nota**  
Essa função só pode ser usada em operações transacionais.

## Sintaxe
<a name="ql-functions.exists.syntax"></a>

```
EXISTS ( statement )
```

## Argumentos
<a name="ql-functions.exists.arguments"></a>

*instrução *  
(Obrigatório) A instrução SELECT que a função avalia.  
A instrução SELECT deve especificar uma chave primária completa e alguma outra condição.

## Tipo de retorno
<a name="ql-functions.exists.return-type"></a>

`bool`

## Exemplos
<a name="ql-functions.exists.examples"></a>

```
EXISTS(
    SELECT * FROM "Music" 
    WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks')
```

# Usar a função BEGINS\$1WITH com PartiQL para DynamoDB
<a name="ql-functions.beginswith"></a>

Retorna `TRUE` quando o atributo especificado começa com uma substring específica.

## Sintaxe
<a name="ql-functions.beginswith.syntax"></a>

```
begins_with(path, value )
```

## Argumentos
<a name="ql-functions.beginswith.arguments"></a>

*path*  
(Obrigatório) O nome do atributo ou o caminho do documento a ser usado.

*value*  
(Obrigatório) A string a ser pesquisada.

## Tipo de retorno
<a name="ql-functions.beginswith.return-type"></a>

`bool`

## Exemplos
<a name="ql-functions.beginswith.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND begins_with("Address", '7834 24th')
```

# Usar a função MISSING com PartiQL para DynamoDB
<a name="ql-functions.missing"></a>

Retorna `TRUE` quando o item não contém o atributo especificado. Somente operadores de igualdade e desigualdade podem ser usados com esta função.

## Sintaxe
<a name="ql-functions.missing.syntax"></a>

```
 attributename IS | IS NOT  MISSING 
```

## Argumentos
<a name="ql-functions.missing.arguments"></a>

*attributename*  
(Obrigatório) O nome do atributo a ser procurado.

## Tipo de retorno
<a name="ql-functions.missing.return-type"></a>

`bool`

## Exemplos
<a name="ql-functions.missing.examples"></a>

```
SELECT * FROM Music WHERE "Awards" is MISSING
```

# Usar a função ATTRIBUTE\$1TYPE com PartiQL para DynamoDB
<a name="ql-functions.attribute_type"></a>

Retorna `TRUE` quando o atributo no caminho especificado é de um tipo de dados específico.

## Sintaxe
<a name="ql-functions.attribute_type.syntax"></a>

```
attribute_type( attributename, type )
```

## Argumentos
<a name="ql-functions.attribute_type.arguments"></a>

*attributename*  
(Obrigatório) O nome do atributo a ser usado.

*tipo*  
(Obrigatório) O tipo de atributo a ser verificado. Para obter uma lista de valores válidos, consulte [attribute\$1type](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) do DynamoDB.

## Tipo de retorno
<a name="ql-functions.attribute_type.return-type"></a>

`bool`

## Exemplos
<a name="ql-functions.attribute_type.examples"></a>

```
SELECT * FROM "Music" WHERE attribute_type("Artist", 'S')
```

# Usar a função CONTAINS com PartiQL para DynamoDB
<a name="ql-functions.contains"></a>

Retorna `TRUE` quando o atributo especificado pelo caminho é um dos seguintes:
+ Uma String que contém uma substring específica. 
+ Um Set que contém um elemento específico dentro do conjunto.

Para obter mais informações, consulte a função [contains](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) do DynamoDB. 

## Sintaxe
<a name="ql-functions.contains.syntax"></a>

```
contains( path, substring )
```

## Argumentos
<a name="ql-functions.contains.arguments"></a>

*path*  
(Obrigatório) O nome do atributo ou o caminho do documento a ser usado.

*substring*  
(Obrigatório) A substring do atributo ou o membro do conjunto a ser verificado. Para obter mais informações, consulte a função [contains](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) do DynamoDB.

## Tipo de retorno
<a name="ql-functions.contains.return-type"></a>

`bool`

## Exemplos
<a name="ql-functions.contains.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND contains("Address", 'Kirkland')
```

# Usar a função SIZE com PartiQL para Amazon DynamoDB
<a name="ql-functions.size"></a>

Retorna um número que representa o tamanho de um atributo em bytes. Veja a seguir os tipos de dados válidos para uso com SIZE. Para obter mais informações, consulte a função [size](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) do DynamoDB.

## Sintaxe
<a name="ql-functions.size.syntax"></a>

```
size( path)
```

## Argumentos
<a name="ql-functions.size.arguments"></a>

*path*  
(Obrigatório) O nome do atributo ou o caminho do documento.   
Para obter os tipos compatíveis, consulte a função [size](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) do DynamoDB.

## Tipo de retorno
<a name="ql-functions.size.return-type"></a>

`int`

## Exemplos
<a name="ql-functions.size.examples"></a>

```
 SELECT * FROM "Orders" WHERE "OrderID"=1 AND size("Image") >300
```

# Operadores aritméticos, comparativos e lógicos de PartiQL para DynamoDB
<a name="ql-operators"></a>

A linguagem PartiQL no Amazon DynamoDB oferece suporte às [instruções SQL padrão](https://www.w3schools.com/sql/sql_operators.asp) a seguir.

**nota**  
Os operadores SQL que não fazem parte desta lista não são aceitas no DynamoDB.

## Operadores aritméticos
<a name="ql-operators.arithmetic"></a>


****  

| Operador | Descrição | 
| --- | --- | 
| \$1 | Adicionar | 
| - | Subtrair | 

## Operadores de comparação
<a name="ql-operators.comparison"></a>


****  

| Operador | Descrição | 
| --- | --- | 
| = | Igual a | 
| <> | Não é igual a | 
| \$1= | Não é igual a | 
| > | Maior que | 
| < | Menor que | 
| >= | Maior ou igual a | 
| <= | Menor ou igual a | 

## Operadores lógicos
<a name="ql-operators.logical"></a>


****  

| Operador | Descrição | 
| --- | --- | 
| AND | TRUE se todas as condições separadas por AND forem TRUE | 
| BETWEEN |  `TRUE` se o operando estiver dentro do intervalo de comparações. Esse operador inclui os limites inferior e superior dos operandos nos quais você o aplica.  | 
| IN | `TRUE` se o operando for igual a um dos valores de uma lista de expressões (no máximo cinquenta valores de atributo hash ou no máximo cem valores de atributo que não sejam chaves). Os resultados são exibidos em páginas com até dez itens. Se a lista `IN` contiver mais valores, será necessário usar o `NextToken` exibido na resposta para recuperar as páginas subsequentes. | 
| IS | TRUE se o operando for um determinado tipo de dados PartiQL, incluindo NULL ou MISSING | 
| NOT | Reverte o valor de uma determinada expressão booleana | 
| OR | TRUE se qualquer uma das condições separadas por OR for TRUE | 

Para obter mais informações sobre como usar operadores lógicos, consulte [Fazer comparações](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Comparators) e [Avaliações lógicas](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.LogicalEvaluations).

# Executar transações com PartiQL para DynamoDB
<a name="ql-reference.multiplestatements.transactions"></a>

Esta seção descreve como usar transações com a linguagem PartiQL para DynamoDB. As transações PartiQL são limitadas a 100 instruções (ações) no total.

Para obter mais informações sobre transações do DynamoDB, consulte [Gerenciar fluxos de trabalho complexos com transações do DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html).

**nota**  
A transação inteira deve ser composta por instruções de leitura ou instruções de gravação. Não é permitido misturar os dois em uma transação. A função EXISTS é uma exceção. Você pode usá-la para verificar a condição de atributos específicos do item de uma maneira semelhante a `ConditionCheck` na operação [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems) da API.

**Topics**
+ [Sintaxe](#ql-reference.multiplestatements.transactions.syntax)
+ [Parâmetros](#ql-reference.multiplestatements.transactions.parameters)
+ [Retornar valores](#ql-reference.multiplestatements.transactions.return)
+ [Exemplos](#ql-reference.multiplestatements.transactions.examples)

## Sintaxe
<a name="ql-reference.multiplestatements.transactions.syntax"></a>

```
[
   {
      "Statement":" statement ",
      "Parameters":[
         {
            " parametertype " : " parametervalue "
         }, ...]
   } , ...
]
```

## Parâmetros
<a name="ql-reference.multiplestatements.transactions.parameters"></a>

***instrução***  
(Obrigatório) Uma instrução valida na linguagem PartiQL para DynamoDB.  
A transação inteira deve ser composta por instruções de leitura ou instruções de gravação. Não é permitido misturar os dois em uma transação.

***parametertype***  
(Opcional) Um tipo do DynamoDB, se parâmetros foram usados ao especificar a instrução PartiQL.

***parametervalue***  
(Opcional) Um valor de parâmetro, se parâmetros foram usados ao especificar a instrução PartiQL.

## Retornar valores
<a name="ql-reference.multiplestatements.transactions.return"></a>

Esta instrução não retorna nenhum valor para operações de gravação (INSERT, UPDATE ou DELETE). No entanto, ela retorna valores diferentes para operações de leitura (SELECT) com base nas condições especificadas na cláusula WHERE.

**nota**  
Se qualquer uma das operações singleton INSERT, UPDATE ou DELETE retornar um erro, as transações serão canceladas com a exceção `TransactionCanceledException` e o código de motivo de cancelamento incluirá os erros das operações singleton individuais.

## Exemplos
<a name="ql-reference.multiplestatements.transactions.examples"></a>

O exemplo a seguir executa várias instruções como uma transação.

------
#### [ AWS CLI ]

1. Salve o seguinte código JSON em um arquivo chamado partiql.json. 

   ```
   [
       {
           "Statement": "EXISTS(SELECT * FROM \"Music\" where Artist='No One You Know' and SongTitle='Call Me Today' and Awards is  MISSING)"
       },
       {
           "Statement": "INSERT INTO Music value {'Artist':?,'SongTitle':'?'}",
           "Parameters": [{\"S\": \"Acme Band\"}, {\"S\": \"Best Song\"}]
       },
       {
           "Statement": "UPDATE \"Music\" SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist='Acme Band' and SongTitle='PartiQL Rocks'"
       }
   ]
   ```

1. Execute o comando a seguir em um prompt de comando.

   ```
   aws dynamodb execute-transaction --transact-statements  file://partiql.json
   ```

------
#### [ Java ]

```
public class DynamoDBPartiqlTransaction {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-2");
        
        try {
            // Create ExecuteTransactionRequest
            ExecuteTransactionRequest executeTransactionRequest = createExecuteTransactionRequest();
            ExecuteTransactionResult executeTransactionResult = dynamoDB.executeTransaction(executeTransactionRequest);
            System.out.println("ExecuteTransaction successful.");
            // Handle executeTransactionResult

        } catch (Exception e) {
            handleExecuteTransactionErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {
        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static ExecuteTransactionRequest createExecuteTransactionRequest() {
        ExecuteTransactionRequest request = new ExecuteTransactionRequest();
        
        // Create statements
        List<ParameterizedStatement> statements = getPartiQLTransactionStatements();

        request.setTransactStatements(statements);
        return request;
    }

    private static List<ParameterizedStatement> getPartiQLTransactionStatements() {
        List<ParameterizedStatement> statements = new ArrayList<ParameterizedStatement>();

        statements.add(new ParameterizedStatement()
                               .withStatement("EXISTS(SELECT * FROM "Music" where Artist='No One You Know' and SongTitle='Call Me Today' and Awards is  MISSING)"));

        statements.add(new ParameterizedStatement()
                               .withStatement("INSERT INTO "Music" value {'Artist':'?','SongTitle':'?'}")
                               .withParameters(new AttributeValue("Acme Band"),new AttributeValue("Best Song")));

        statements.add(new ParameterizedStatement()
                               .withStatement("UPDATE "Music" SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist='Acme Band' and SongTitle='PartiQL Rocks'"));

        return statements;
    }

    // Handles errors during ExecuteTransaction execution. Use recommendations in error messages below to add error handling specific to 
    // your application use-case.
    private static void handleExecuteTransactionErrors(Exception exception) {
        try {
            throw exception;
        } catch (TransactionCanceledException tce) {
            System.out.println("Transaction Cancelled, implies a client issue, fix before retrying. Error: " + tce.getErrorMessage());
        } catch (TransactionInProgressException tipe) {
            System.out.println("The transaction with the given request token is already in progress, consider changing " +
                "retry strategy for this type of error. Error: " + tipe.getErrorMessage());
        } catch (IdempotentParameterMismatchException ipme) {
            System.out.println("Request rejected because it was retried with a different payload but with a request token that was already used, " +
                "change request token for this payload to be accepted. Error: " + ipme.getErrorMessage());
        } catch (Exception e) {
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " + 
                "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " + 
                ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " + 
                "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

O exemplo a seguir mostra os diferentes valores de retorno quando o DynamoDB lê itens com diferentes condições especificadas na cláusula WHERE.

------
#### [ AWS CLI ]

1. Salve o seguinte código JSON em um arquivo chamado partiql.json.

   ```
   [
       // Item exists and projected attribute exists
       {
           "Statement": "SELECT * FROM "Music" WHERE Artist='No One You Know' and SongTitle='Call Me Today'"
       },
       // Item exists but projected attributes do not exist
       {
           "Statement": "SELECT non_existent_projected_attribute FROM "Music" WHERE Artist='No One You Know' and SongTitle='Call Me Today'"
       },
       // Item does not exist
       {
           "Statement": "SELECT * FROM "Music" WHERE Artist='No One I Know' and SongTitle='Call You Today'"
       }
   ]
   ```

1.  comando a seguir em um prompt de comando.

   ```
   aws dynamodb execute-transaction --transact-statements  file://partiql.json
   ```

1. A resposta a seguir será retornada:

   ```
   {
       "Responses": [
           // Item exists and projected attribute exists
           {
               "Item": {
                   "Artist":{
                       "S": "No One You Know"
                   },
                   "SongTitle":{
                       "S": "Call Me Today"
                   }    
               }
           },
           // Item exists but projected attributes do not exist
           {
               "Item": {}
           },
           // Item does not exist
           {}
       ]
   }
   ```

------

# Executar operações em lote com PartiQL para DynamoDB
<a name="ql-reference.multiplestatements.batching"></a>

Esta seção descreve como usar instruções em lote com a linguagem PartiQL para DynamoDB.

**nota**  
O lote inteiro deve consistir em instruções de leitura ou instruções de gravação; não é possível misturar ambas em um lote.
`BatchExecuteStatement` e `BatchWriteItem` podem executar mais de 25 instruções por lote.
O `BatchExecuteStatement` faz uso do `BatchGetItem` que utiliza uma lista de chaves primárias em declarações separadas.

**Topics**
+ [Sintaxe](#ql-reference.multiplestatements.batching.syntax)
+ [Parâmetros](#ql-reference.multiplestatements.batching.parameters)
+ [Exemplos](#ql-reference.multiplestatements.batching.examples)

## Sintaxe
<a name="ql-reference.multiplestatements.batching.syntax"></a>

```
[
  {
    "Statement": "SELECT pk FROM ProblemSet WHERE pk = 'p#9StkWHYTxm7x2AqSXcrfu7' AND sk = 'info'"
  },
  {
    "Statement": "SELECT pk FROM ProblemSet WHERE pk = 'p#isC2ChceGbxHgESc4szoTE' AND sk = 'info'"
  }
]
```

```
[
   {
      "Statement":" statement ",
      "Parameters":[
         {
            " parametertype " : " parametervalue "
         }, ...]
   } , ...
]
```

## Parâmetros
<a name="ql-reference.multiplestatements.batching.parameters"></a>

***instrução***  
(Obrigatório) Uma instrução valida na linguagem PartiQL para DynamoDB.  
+ O lote inteiro deve consistir em instruções de leitura ou instruções de gravação; não é possível misturar ambas em um lote.
+ `BatchExecuteStatement` e `BatchWriteItem` podem executar mais de 25 instruções por lote.

***parametertype***  
(Opcional) Um tipo do DynamoDB, se parâmetros foram usados ao especificar a instrução PartiQL.

***parametervalue***  
(Opcional) Um valor de parâmetro, se parâmetros foram usados ao especificar a instrução PartiQL.

## Exemplos
<a name="ql-reference.multiplestatements.batching.examples"></a>

------
#### [ AWS CLI ]

1. Salve o seguinte json em um arquivo chamado partiql.json

   ```
   [
      {
   	 "Statement": "INSERT INTO Music VALUE {'Artist':?,'SongTitle':?}",
   	  "Parameters": [{"S": "Acme Band"}, {"S": "Best Song"}]
   	},
   	{
   	 "Statement": "UPDATE Music SET AwardsWon=1, AwardDetail={'Grammys':[2020, 2018]} WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
       }
   ]
   ```

1. Execute o comando a seguir em um prompt de comando.

   ```
   aws dynamodb batch-execute-statement  --statements  file://partiql.json
   ```

------
#### [ Java ]

```
public class DynamoDBPartiqlBatch {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-2");
        
        try {
            // Create BatchExecuteStatementRequest
            BatchExecuteStatementRequest batchExecuteStatementRequest = createBatchExecuteStatementRequest();
            BatchExecuteStatementResult batchExecuteStatementResult = dynamoDB.batchExecuteStatement(batchExecuteStatementRequest);
            System.out.println("BatchExecuteStatement successful.");
            // Handle batchExecuteStatementResult

        } catch (Exception e) {
            handleBatchExecuteStatementErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {

        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static BatchExecuteStatementRequest createBatchExecuteStatementRequest() {
        BatchExecuteStatementRequest request = new BatchExecuteStatementRequest();

        // Create statements
        List<BatchStatementRequest> statements = getPartiQLBatchStatements();

        request.setStatements(statements);
        return request;
    }

    private static List<BatchStatementRequest> getPartiQLBatchStatements() {
        List<BatchStatementRequest> statements = new ArrayList<BatchStatementRequest>();

        statements.add(new BatchStatementRequest()
                               .withStatement("INSERT INTO Music value {'Artist':'Acme Band','SongTitle':'PartiQL Rocks'}"));

        statements.add(new BatchStatementRequest()
                               .withStatement("UPDATE Music set AwardDetail.BillBoard=[2020] where Artist='Acme Band' and SongTitle='PartiQL Rocks'"));

        return statements;
    }

    // Handles errors during BatchExecuteStatement execution. Use recommendations in error messages below to add error handling specific to 
    // your application use-case.
    private static void handleBatchExecuteStatementErrors(Exception exception) {
        try {
            throw exception;
        } catch (Exception e) {
            // There are no API specific errors to handle for BatchExecuteStatement, common DynamoDB API errors are handled below
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " + 
                "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " + 
                ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " + 
                "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

# Políticas de segurança do IAM com PartiQL para DynamoDB
<a name="ql-iam"></a>

As seguintes permissões são necessárias:
+ Para ler itens usando PartiQL para DynamoDB, é necessário ter a permissão `dynamodb:PartiQLSelect` na tabela ou no índice.
+ Para inserir itens usando PartiQL para DynamoDB, é necessário ter a permissão `dynamodb:PartiQLInsert` na tabela ou no índice.
+ Para atualizar itens usando PartiQL para DynamoDB, é necessário ter a permissão `dynamodb:PartiQLUpdate` na tabela ou no índice.
+ Para excluir itens usando PartiQL para DynamoDB, é necessário ter a permissão `dynamodb:PartiQLDelete` na tabela ou no índice.

## Exemplo: permitir todas as instruções PartiQL para DynamoDB (Select/Insert/Update/Delete) em uma tabela
<a name="access-policy-ql-iam-example1"></a>

A política do IAM a seguir concede permissões para executar todas as instruções PartiQL para DynamoDB em uma tabela. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## Exemplo: permitir instruções Select PartiQL para DynamoDB em uma tabela
<a name="access-policy-ql-iam-example2"></a>

A política do IAM a seguir concede permissões para executar a instrução `select` em uma tabela específica.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## Exemplo: permitir instruções Insert PartiQL para DynamoDB em um índice
<a name="access-policy-ql-iam-example3"></a>

A política do IAM a seguir concede permissões para executar a instrução `insert` em um índice específico. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music/index/index1"
         ]
      }
   ]
}
```

------

## Exemplo: permitir instruções transacionais PartiQL para DynamoDB somente em uma tabela
<a name="access-policy-ql-iam-example4"></a>

A política do IAM a seguir concede permissões para executar somente instruções transacionais em uma tabela específica. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ],
         "Condition":{
            "StringEquals":{
               "dynamodb:EnclosingOperation":[
                  "ExecuteTransaction"
               ]
            }
         }
      }
   ]
}
```

------

## Exemplo: permitir leituras e gravações não transacionais PartiQL para DynamoDB e bloquear leituras e gravações transacionais PartiQL em uma tabela.
<a name="access-policy-ql-iam-example5"></a>

 A política do IAM a seguir concede permissões para executar leituras e gravações não transacionais PartiQL para DynamoDB ao mesmo tempo que bloqueia leituras e gravações transacionais PartiQL para DynamoDB.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Deny",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ],
         "Condition":{
            "StringEquals":{
               "dynamodb:EnclosingOperation":[
                  "ExecuteTransaction"
               ]
            }
         }
      },
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## Exemplo: permitir instruções Select e negar instruções de verificação de tabela completa em PartiQL para DynamoDB
<a name="access-policy-ql-iam-example6"></a>

A política do IAM a seguir concede permissões para executar a instrução `select` em uma tabela específica ao mesmo tempo que bloqueia instruções `select` que resultam em uma verificação de tabela completa.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Deny",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/WatchList"
         ],
         "Condition":{
            "Bool":{
               "dynamodb:FullTableScan":[
                  "true"
               ]
            }
         }
      },
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/WatchList"
         ]
      }
   ]
}
```

------

# Trabalhar com itens: Java
<a name="JavaDocumentAPIItemCRUD"></a>

Você pode usar a API de documentos do AWS SDK para Java para realizar operações create, read, update e delete (CRUD) típicas nos itens do Amazon DynamoDB em uma tabela.

**nota**  
O SDK for Java também fornece um modelo de persistência de objetos que permite que você mapeie suas classes do lado do cliente para tabelas do DynamoDB. Essa abordagem pode reduzir a quantidade de código que você precisa escrever. Para obter mais informações, consulte [Java 1.x: DynamoDBMapper](DynamoDBMapper.md).

Esta seção contém exemplos de Java para executar várias ações de itens da API de documento do Java e vários exemplos funcionais completos.

**Topics**
+ [Colocar um item](#PutDocumentAPIJava)
+ [Obter um item](#JavaDocumentAPIGetItem)
+ [Gravação em lote: colocar e excluir vários itens](#BatchWriteDocumentAPIJava)
+ [Obtenção em lote: obter vários itens](#JavaDocumentAPIBatchGetItem)
+ [Atualizar um item](#JavaDocumentAPIItemUpdate)
+ [Excluir um item](#DeleteMidLevelJava)
+ [Exemplo: operações CRUD usando a API de documento do AWS SDK para Java](JavaDocumentAPICRUDExample.md)
+ [Exemplo: operações em lote usando a API de documento do AWS SDK para Java](batch-operation-document-api-java.md)
+ [Exemplo: tratar atributos do tipo binário usando a API de documento do AWS SDK para Java](JavaDocumentAPIBinaryTypeExample.md)

## Colocar um item
<a name="PutDocumentAPIJava"></a>

O método `putItem` armazena um item em uma tabela. Se o item existe, ele substitui o item inteiro. Em vez de substituir o item inteiro, se você quiser atualizar apenas atributos específicos, use o método `updateItem`. Para obter mais informações, consulte [Atualizar um item](#JavaDocumentAPIItemUpdate). 

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import java.util.HashMap;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To place items into an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client. See the EnhancedPutItem example.
 */
public class PutItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal> <albumtitle> <albumtitleval> <awards> <awardsval> <Songtitle> <songtitleval>

                Where:
                    tableName - The Amazon DynamoDB table in which an item is placed (for example, Music3).
                    key - The key used in the Amazon DynamoDB table (for example, Artist).
                    keyval - The key value that represents the item to get (for example, Famous Band).
                    albumTitle - The Album title (for example, AlbumTitle).
                    AlbumTitleValue - The name of the album (for example, Songs About Life ).
                    Awards - The awards column (for example, Awards).
                    AwardVal - The value of the awards (for example, 10).
                    SongTitle - The song title (for example, SongTitle).
                    SongTitleVal - The value of the song title (for example, Happy Day).
                **Warning** This program will  place an item that you specify into a table!
                """;

        if (args.length != 9) {
            System.out.println(usage);
            System.exit(1);
        }

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        String albumTitle = args[3];
        String albumTitleValue = args[4];
        String awards = args[5];
        String awardVal = args[6];
        String songTitle = args[7];
        String songTitleVal = args[8];

        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        putItemInTable(ddb, tableName, key, keyVal, albumTitle, albumTitleValue, awards, awardVal, songTitle,
                songTitleVal);
        System.out.println("Done!");
        ddb.close();
    }

    public static void putItemInTable(DynamoDbClient ddb,
            String tableName,
            String key,
            String keyVal,
            String albumTitle,
            String albumTitleValue,
            String awards,
            String awardVal,
            String songTitle,
            String songTitleVal) {

        HashMap<String, AttributeValue> itemValues = new HashMap<>();
        itemValues.put(key, AttributeValue.builder().s(keyVal).build());
        itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build());
        itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build());
        itemValues.put(awards, AttributeValue.builder().s(awardVal).build());

        PutItemRequest request = PutItemRequest.builder()
                .tableName(tableName)
                .item(itemValues)
                .build();

        try {
            PutItemResponse response = ddb.putItem(request);
            System.out.println(tableName + " was successfully updated. The request id is "
                    + response.responseMetadata().requestId());

        } catch (ResourceNotFoundException e) {
            System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName);
            System.err.println("Be sure that it exists and that you've typed its name correctly!");
            System.exit(1);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

------
#### [ Java v1 ]

Siga estas etapas: 

1. Crie uma instância da classe `DynamoDB`.

1. Crie uma instância da classe `Table` para representar a tabela com a qual você deseja trabalhar.

1. Crie uma instância da classe `Item` para representar o novo item. Você deve especificar a chave primária do novo item e seus atributos.

1. Chame o método `putItem` do objeto `Table`, usando o `Item` que você criou na etapa anterior.

O exemplo de código Java a seguir demonstra as tarefas anteriores. O código grava um novo item na tabela `ProductCatalog`.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

// Build a list of related items
List<Number> relatedItems = new ArrayList<Number>();
relatedItems.add(341);
relatedItems.add(472);
relatedItems.add(649);

//Build a map of product pictures
Map<String, String> pictures = new HashMap<String, String>();
pictures.put("FrontView", "http://example.com/products/123_front.jpg");
pictures.put("RearView", "http://example.com/products/123_rear.jpg");
pictures.put("SideView", "http://example.com/products/123_left_side.jpg");

//Build a map of product reviews
Map<String, List<String>> reviews = new HashMap<String, List<String>>();

List<String> fiveStarReviews = new ArrayList<String>();
fiveStarReviews.add("Excellent! Can't recommend it highly enough!  Buy it!");
fiveStarReviews.add("Do yourself a favor and buy this");
reviews.put("FiveStar", fiveStarReviews);

List<String> oneStarReviews = new ArrayList<String>();
oneStarReviews.add("Terrible product!  Do not buy this.");
reviews.put("OneStar", oneStarReviews);

// Build the item
Item item = new Item()
    .withPrimaryKey("Id", 123)
    .withString("Title", "Bicycle 123")
    .withString("Description", "123 description")
    .withString("BicycleType", "Hybrid")
    .withString("Brand", "Brand-Company C")
    .withNumber("Price", 500)
    .withStringSet("Color",  new HashSet<String>(Arrays.asList("Red", "Black")))
    .withString("ProductCategory", "Bicycle")
    .withBoolean("InStock", true)
    .withNull("QuantityOnHand")
    .withList("RelatedItems", relatedItems)
    .withMap("Pictures", pictures)
    .withMap("Reviews", reviews);

// Write the item to the table
PutItemOutcome outcome = table.putItem(item);
```

No exemplo anterior, o item tem atributos que são escalares (`String`, `Number`, `Boolean`, `Null`), conjuntos (`String Set`) e tipos de documento (`List`, `Map`).

------

### Especificar parâmetros opcionais
<a name="PutItemJavaDocumentAPIOptions"></a>

Além dos parâmetros obrigatórios, você também pode especificar parâmetros opcionais para o método `putItem`. Por exemplo, o seguinte exemplo de código Java usa um parâmetro opcional para especificar uma condição para fazer upload do item. Se a condição que você especificar não for atendida, o AWS SDK para Java lançará uma `ConditionalCheckFailedException`. O exemplo de código especifica os seguintes parâmetros opcionais no método `putItem`:
+ Uma `ConditionExpression` que define as condições para a solicitação. O código define a condição de que o item existente com a mesma chave primária será substituído somente se tiver um atributo ISBN igual a um valor específico. 
+ Um mapa para `ExpressionAttributeValues` que é usado na condição. Nesse caso, existe apenas uma substituição obrigatória: o espaço reservado `:val` na expressão de condição é substituído em tempo de execução pelo valor de ISBN real a ser verificado.

O exemplo a seguir adiciona um novo item de livro usando esses parâmetros opcionais.

**Example**  

```
Item item = new Item()
    .withPrimaryKey("Id", 104)
    .withString("Title", "Book 104 Title")
    .withString("ISBN", "444-4444444444")
    .withNumber("Price", 20)
    .withStringSet("Authors",
        new HashSet<String>(Arrays.asList("Author1", "Author2")));

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val", "444-4444444444");

PutItemOutcome outcome = table.putItem(
    item,
    "ISBN = :val", // ConditionExpression parameter
    null,          // ExpressionAttributeNames parameter - we're not using it for this example
    expressionAttributeValues);
```

### PutItem e documentos JSON
<a name="PutItemJavaDocumentAPI.JSON"></a>

Você pode armazenar um documento JSON como um atributo em uma tabela do DynamoDB. Para fazer isso, use o método `withJSON` de `Item`. Esse método analisa o documento JSON e mapeia cada elemento em um tipo de dados nativo do DynamoDB.

Suponha que você quisesse armazenar o seguinte documento JSON que contém os fornecedores que podem atender a pedidos de um determinado produto.

**Example**  

```
{
    "V01": {
        "Name": "Acme Books",
        "Offices": [ "Seattle" ]
    },
    "V02": {
        "Name": "New Publishers, Inc.",
        "Offices": ["London", "New York"
        ]
    },
    "V03": {
        "Name": "Better Buy Books",
        "Offices": [ "Tokyo", "Los Angeles", "Sydney"
        ]
    }
}
```

Você pode usar o método `withJSON` para armazenar essas informações na tabela `ProductCatalog`, em um atributo `Map` chamado `VendorInfo`. O exemplo de código Java a seguir demonstra como fazer isso.

```
// Convert the document into a String.  Must escape all double-quotes.
String vendorDocument = "{"
    + "    \"V01\": {"
    + "        \"Name\": \"Acme Books\","
    + "        \"Offices\": [ \"Seattle\" ]"
    + "    },"
    + "    \"V02\": {"
    + "        \"Name\": \"New Publishers, Inc.\","
    + "        \"Offices\": [ \"London\", \"New York\"" + "]" + "},"
    + "    \"V03\": {"
    + "        \"Name\": \"Better Buy Books\","
    +          "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\""
    + "            ]"
    + "        }"
    + "    }";

Item item = new Item()
    .withPrimaryKey("Id", 210)
    .withString("Title", "Book 210 Title")
    .withString("ISBN", "210-2102102102")
    .withNumber("Price", 30)
    .withJSON("VendorInfo", vendorDocument);

PutItemOutcome outcome = table.putItem(item);
```

## Obter um item
<a name="JavaDocumentAPIGetItem"></a>

Para recuperar um único item, use o método `getItem` de um objeto `Table`. Siga estas etapas: 

1. Crie uma instância da classe `DynamoDB`.

1. Crie uma instância da classe `Table` para representar a tabela com a qual você deseja trabalhar.

1. Chame o método `getItem` de instância de `Table`. Você deve especificar a chave primária do item que deseja recuperar.

O exemplo de código Java a seguir demonstra as etapas anteriores. O código obtém o item que tem a chave de partição especificada.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Item item = table.getItem("Id", 210);
```

### Especificar parâmetros opcionais
<a name="GetItemJavaDocumentAPIOptions"></a>

Além dos parâmetros obrigatórios, você também pode especificar parâmetros opcionais do método `getItem`. Por exemplo, o seguinte exemplo de código Java usa um método opcional para recuperar somente uma lista específica de atributos e para especificar leituras fortemente consistentes. (Para saber mais sobre a consistência de leitura, consulte [Consistência de leitura do DynamoDB](HowItWorks.ReadConsistency.md).)

Você pode usar uma `ProjectionExpression` para recuperar somente atributos ou elementos específicos, em vez de todo o item. A `ProjectionExpression` pode especificar atributos aninhados ou de alto nível, usando caminhos de documentos. Para obter mais informações, consulte [Usar expressões de projeção no DynamoDB](Expressions.ProjectionExpressions.md).

Os parâmetros do método `getItem` não permitem que você especifique consistência de leitura. No entanto, você pode criar uma `GetItemSpec` que dá acesso total a todas as entradas para a operação `GetItem` de baixo nível. O exemplo de código a seguir cria uma `GetItemSpec` e usa essa especificação como entrada para o método `getItem`.

**Example**  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 206)
    .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar")
    .withConsistentRead(true);

Item item = table.getItem(spec);

System.out.println(item.toJSONPretty());
```

 Para imprimir um `Item` em um formato legível, use o método `toJSONPretty`. A saída do exemplo anterior é semelhante à seguinte.

```
{
  "RelatedItems" : [ 341 ],
  "Reviews" : {
    "FiveStar" : [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this" ]
  },
  "Id" : 123,
  "Title" : "20-Bicycle 123"
}
```

### GetItem e documentos JSON
<a name="GetItemJavaDocumentAPI.JSON"></a>

Na seção [PutItem e documentos JSON](#PutItemJavaDocumentAPI.JSON), você armazenou um documento JSON em um atributo `Map` chamado `VendorInfo`. Você pode usar o método `getItem` para recuperar o documento inteiro no formato JSON. Ou pode usar a notação do caminho do documento para recuperar apenas alguns dos elementos no documento. O exemplo de código Java a seguir demonstra essas técnicas.

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210);

System.out.println("All vendor info:");
spec.withProjectionExpression("VendorInfo");
System.out.println(table.getItem(spec).toJSON());

System.out.println("A single vendor:");
spec.withProjectionExpression("VendorInfo.V03");
System.out.println(table.getItem(spec).toJSON());

System.out.println("First office location for this vendor:");
spec.withProjectionExpression("VendorInfo.V03.Offices[0]");
System.out.println(table.getItem(spec).toJSON());
```

A saída do exemplo anterior é semelhante à seguinte.

```
All vendor info:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices":["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}}
A single vendor:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}}
First office location for a single vendor:
{"VendorInfo":{"V03":{"Offices":["Tokyo"]}}}
```

**nota**  
Você pode usar o método `toJSON` para converter qualquer item (ou seus atributos) em uma string formatada para JSON. O exemplo de código a seguir recupera vários atributos aninhados e de alto nível e imprime os resultados como JSON.  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210)
    .withProjectionExpression("VendorInfo.V01, Title, Price");

Item item = table.getItem(spec);
System.out.println(item.toJSON());
```
A saída é semelhante à seguinte.  

```
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}
```

## Gravação em lote: colocar e excluir vários itens
<a name="BatchWriteDocumentAPIJava"></a>

*Gravação em lote* se refere a inserir e excluir vários itens em um lote. O método `batchWriteItem` permite que você insira e exclua vários itens de uma ou mais tabelas em uma única chamada. Veja a seguir as etapas para inserir ou excluir vários itens usando a API de documento do AWS SDK para Java.

1. Crie uma instância da classe `DynamoDB`.

1. Crie uma instância da classe `TableWriteItems` que descreve todas as operações Put e Delete de uma tabela. Se você quiser gravar em várias tabelas com uma única operação de gravação em lote, crie uma instância de `TableWriteItems` por tabela.

1. Chame o método `batchWriteItem`, fornecendo os objetos `TableWriteItems` que você criou na etapa anterior. 

1. Processe a resposta. Você deve verificar se há itens de solicitação não processados retornados na resposta. Isso poderá acontecer se você atingir a cota de throughput provisionado ou por algum outro erro temporário. Além disso, o DynamoDB limita o tamanho da solicitação e o número de operações que você pode especificar em uma solicitação. Se você exceder esses limites, o DynamoDB rejeitará a solicitação. Para obter mais informações, consulte [Cotas no Amazon DynamoDB](ServiceQuotas.md). 

O exemplo de código Java a seguir demonstra as etapas anteriores. O exemplo executa uma operação `batchWriteItem` em duas tabelas: `Forum` e `Thread`. Os objetos `TableWriteItems` correspondentes definem as seguintes ações:
+ Inserir um item na tabela `Forum`.
+ Inserir e excluir um item na tabela `Thread`.

O código chama `batchWriteItem` para executar a operação.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

TableWriteItems forumTableWriteItems = new TableWriteItems("Forum")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("Name", "Amazon RDS")
            .withNumber("Threads", 0));

TableWriteItems threadTableWriteItems = new TableWriteItems("Thread")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1")
    .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value");

BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

// Code for checking unprocessed items is omitted in this example
```

Para obter um exemplo funcional, consulte [Exemplo: operação de gravação em lote usando a API de documento do AWS SDK para Java](batch-operation-document-api-java.md#JavaDocumentAPIBatchWrite). 

## Obtenção em lote: obter vários itens
<a name="JavaDocumentAPIBatchGetItem"></a>

O método `batchGetItem` permite que você recupere vários itens de uma ou mais tabelas. Para recuperar um único item, você pode usar o método `getItem`. 

Siga estas etapas: 

1. Crie uma instância da classe `DynamoDB`.

1. Crie uma instância da classe `TableKeysAndAttributes` que descreve uma lista de valores de chave primária para recuperar de uma tabela. Se você desejar ler em várias tabelas em uma única operação de aquisição em lote, será necessário criar uma instância de `TableKeysAndAttributes` por tabela.

1. Chame o método `batchGetItem`, fornecendo os objetos `TableKeysAndAttributes` que você criou na etapa anterior.

O exemplo de código Java a seguir demonstra as etapas anteriores. O exemplo recupera dois itens da tabela `Forum` e três itens da tabela `Thread`.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

    TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
    forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject",
    "Amazon DynamoDB","DynamoDB Thread 1",
    "Amazon DynamoDB","DynamoDB Thread 2",
    "Amazon S3","S3 Thread 1");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(
    forumTableKeysAndAttributes, threadTableKeysAndAttributes);

for (String tableName : outcome.getTableItems().keySet()) {
    System.out.println("Items in table " + tableName);
    List<Item> items = outcome.getTableItems().get(tableName);
    for (Item item : items) {
        System.out.println(item);
    }
}
```

### Especificar parâmetros opcionais
<a name="BatchGetItemJavaDocumentAPIOptions"></a>

Além dos parâmetros obrigatórios, você também pode especificar parâmetros opcionais ao usar `batchGetItem`. Por exemplo, você pode fornecer uma `ProjectionExpression` com cada `TableKeysAndAttributes` que você definir. Isso permite que você especifique os atributos que deseja recuperar da tabela.

O exemplo de código a seguir recupera dois itens da tabela `Forum`. O parâmetro `withProjectionExpression` especifica que apenas o atributo `Threads` deve ser recuperado.

**Example**  

```
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum")
    .withProjectionExpression("Threads");

forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
```

## Atualizar um item
<a name="JavaDocumentAPIItemUpdate"></a>

O método `updateItem` de um objeto `Table` pode atualizar valores de atributo existentes, adicionar novos atributos ou excluir atributos de um item existente. 

O método `updateItem` se comporta da seguinte forma:
+ Se não existir um item (não houver nenhum item na tabela com a chave primária especificada), `updateItem` adicionará um novo item à tabela
+ Se existir um item, `updateItem` executará a atualização conforme especificado pelo parâmetro `UpdateExpression`.

**nota**  
Também é possível "atualizar" um item usando `putItem`. Por exemplo, se você chamar `putItem` para adicionar um item à tabela, mas já existir um item com a chave primária especificada, `putItem` substituirá o item inteiro. Se houver atributos no item existente que não são especificados na entrada, `putItem` removerá esses atributos do item.  
Em geral, recomendamos que você use `updateItem` sempre que desejar modificar quaisquer atributos de item. O método `updateItem` só modifica os atributos de item que você especifica na entrada, e os outros atributos no item permanecem inalterados.

Siga estas etapas: 

1. Crie uma instância da classe `Table` para representar a tabela com a qual você deseja trabalhar.

1. Chame o método `updateTable` de instância de `Table`. Você deve especificar a chave primária do item que deseja recuperar, juntamente com uma `UpdateExpression` que descreve os atributos a serem modificados e como modificá-los.

O exemplo de código Java a seguir demonstra as tarefas anteriores. O código atualiza um item na tabela `ProductCatalog`. Ele adiciona um novo autor ao conjunto de `Authors` e exclui o atributo `ISBN` existente. Ele também reduz o preço por um.

Um mapa `ExpressionAttributeValues` é usado na `UpdateExpression`. Os espaços reservados `:val1` e `:val2` serão substituídos em tempo de execução pelos valores reais de `Authors` e `Price`.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#A", "Authors");
expressionAttributeNames.put("#P", "Price");
expressionAttributeNames.put("#I", "ISBN");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1",
    new HashSet<String>(Arrays.asList("Author YY","Author ZZ")));
expressionAttributeValues.put(":val2", 1);   //Price

UpdateItemOutcome outcome =  table.updateItem(
    "Id",          // key attribute name
    101,           // key attribute value
    "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### Especificar parâmetros opcionais
<a name="UpdateItemJavaDocumentAPIOptions"></a>

Além dos parâmetros obrigatórios, você também pode especificar parâmetros opcionais para o método `updateItem`, incluindo uma condição que deve ser atendida para que a atualização ocorra. Se a condição que você especificar não for atendida, o AWS SDK para Java lançará uma `ConditionalCheckFailedException`. Por exemplo, o seguinte exemplo de código Java atualiza condicionalmente o preço de item de um livro para 25. Ele especifica uma `ConditionExpression` que declara que o preço deve ser atualizado somente se o preço existente for 20.

**Example**  

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#P", "Price");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1", 25);  // update Price to 25...
expressionAttributeValues.put(":val2", 20);  //...but only if existing Price is 20

UpdateItemOutcome outcome = table.updateItem(
    new PrimaryKey("Id",101),
    "set #P = :val1", // UpdateExpression
    "#P = :val2",     // ConditionExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### Contador atômico
<a name="AtomicCounterJavaDocumentAPI"></a>

Você pode usar `updateItem` para implementar um contador atômico, onde pode aumentar ou reduzir o valor de um atributo existente sem interferir em outras solicitações de gravação. Para aumentar um contador atômico, use uma `UpdateExpression` com uma ação `set` para adicionar um valor numérico a um atributo existente do tipo `Number`.

O exemplo de código a seguir demonstra isso incrementando o atributo `Quantity` em um. Ele também demonstra o uso do parâmetro `ExpressionAttributeNames` em uma `UpdateExpression`.

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String,String> expressionAttributeNames = new HashMap<String,String>();
expressionAttributeNames.put("#p", "PageCount");

Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", 1);

UpdateItemOutcome outcome = table.updateItem(
    "Id", 121,
    "set #p = #p + :val",
    expressionAttributeNames,
    expressionAttributeValues);
```

## Excluir um item
<a name="DeleteMidLevelJava"></a>

O método `deleteItem` exclui um item de uma tabela. É necessário fornecer a chave primária do item que você deseja excluir.

Siga estas etapas: 

1. Crie uma instância do cliente `DynamoDB`.

1. Chame o método `deleteItem`, fornecendo a chave do item que você deseja excluir. 

O exemplo de código Java a seguir demonstra essas tarefas.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

DeleteItemOutcome outcome = table.deleteItem("Id", 101);
```

### Especificar parâmetros opcionais
<a name="DeleteItemJavaDocumentAPIOptions"></a>

Você pode especificar parâmetros opcionais para `deleteItem`. Por exemplo, o seguinte exemplo de código Java especifica uma `ConditionExpression` que declara que um item de livro em `ProductCatalog` só pode ser excluído se o livro não estiver mais em publicação (o atributo `InPublication` é falso).

**Example**  

```
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", false);

DeleteItemOutcome outcome = table.deleteItem("Id",103,
    "InPublication = :val",
    null, // ExpressionAttributeNames - not used in this example
    expressionAttributeValues);
```

# Exemplo: operações CRUD usando a API de documento do AWS SDK para Java
<a name="JavaDocumentAPICRUDExample"></a>

O exemplo de código a seguir ilustra operações CRUD em um item do Amazon DynamoDB. O exemplo cria um item, o recupera, executa várias atualizações e, por fim, o exclui.

**nota**  
O SDK for Java também fornece um modelo de persistência de objetos que permite que você mapeie suas classes do lado do cliente para tabelas do DynamoDB. Essa abordagem pode reduzir a quantidade de código que você precisa escrever. Para obter mais informações, consulte [Java 1.x: DynamoDBMapper](DynamoDBMapper.md).

**nota**  
Este exemplo de código pressupõe que você já carregou dados no DynamoDB para sua conta seguindo as instruções na seção [Criar tabelas e carregar dados para exemplos de código no DynamoDB](SampleData.md).  
Para obter instruções passo a passo sobre como executar o exemplo a seguir, consulte [Exemplos de código Java](CodeSamples.Java.md).

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome;
import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.amazonaws.services.dynamodbv2.model.ReturnValue;

public class DocumentAPIItemCRUDExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String tableName = "ProductCatalog";

    public static void main(String[] args) throws IOException {

        createItems();

        retrieveItem();

        // Perform various updates.
        updateMultipleAttributes();
        updateAddNewAttribute();
        updateExistingAttributeConditionally();

        // Delete the item.
        deleteItem();

    }

    private static void createItems() {

        Table table = dynamoDB.getTable(tableName);
        try {

            Item item = new Item().withPrimaryKey("Id", 120).withString("Title", "Book 120 Title")
                    .withString("ISBN", "120-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author12", "Author22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", false).withString("ProductCategory", "Book");
            table.putItem(item);

            item = new Item().withPrimaryKey("Id", 121).withString("Title", "Book 121 Title")
                    .withString("ISBN", "121-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author21", "Author 22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", true).withString("ProductCategory", "Book");
            table.putItem(item);

        } catch (Exception e) {
            System.err.println("Create items failed.");
            System.err.println(e.getMessage());

        }
    }

    private static void retrieveItem() {
        Table table = dynamoDB.getTable(tableName);

        try {

            Item item = table.getItem("Id", 120, "Id, ISBN, Title, Authors", null);

            System.out.println("Printing item after retrieving it....");
            System.out.println(item.toJSONPretty());

        } catch (Exception e) {
            System.err.println("GetItem failed.");
            System.err.println(e.getMessage());
        }

    }

    private static void updateAddNewAttribute() {
        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 121)
                    .withUpdateExpression("set #na = :val1").withNameMap(new NameMap().with("#na", "NewAttribute"))
                    .withValueMap(new ValueMap().withString(":val1", "Some value"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after adding new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to add new attribute in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void updateMultipleAttributes() {

        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withUpdateExpression("add #a :val1 set #na=:val2")
                    .withNameMap(new NameMap().with("#a", "Authors").with("#na", "NewAttribute"))
                    .withValueMap(
                            new ValueMap().withStringSet(":val1", "Author YY", "Author ZZ").withString(":val2",
                                    "someValue"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after multiple attribute update...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to update multiple attributes in " + tableName);
            System.err.println(e.getMessage());

        }
    }

    private static void updateExistingAttributeConditionally() {

        Table table = dynamoDB.getTable(tableName);

        try {

            // Specify the desired price (25.00) and also the condition (price =
            // 20.00)

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withReturnValues(ReturnValue.ALL_NEW).withUpdateExpression("set #p = :val1")
                    .withConditionExpression("#p = :val2").withNameMap(new NameMap().with("#p", "Price"))
                    .withValueMap(new ValueMap().withNumber(":val1", 25).withNumber(":val2", 20));

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after conditional update to new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error updating item in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void deleteItem() {

        Table table = dynamoDB.getTable(tableName);

        try {

            DeleteItemSpec deleteItemSpec = new DeleteItemSpec().withPrimaryKey("Id", 120)
                    .withConditionExpression("#ip = :val").withNameMap(new NameMap().with("#ip", "InPublication"))
                    .withValueMap(new ValueMap().withBoolean(":val", false)).withReturnValues(ReturnValue.ALL_OLD);

            DeleteItemOutcome outcome = table.deleteItem(deleteItemSpec);

            // Check the response.
            System.out.println("Printing item that was deleted...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error deleting item in " + tableName);
            System.err.println(e.getMessage());
        }
    }
}
```

# Exemplo: operações em lote usando a API de documento do AWS SDK para Java
<a name="batch-operation-document-api-java"></a>

Esta seção fornece exemplos de operações de gravação e aquisição em lote no Amazon DynamoDB usando a API de documentos do AWS SDK para Java.

**nota**  
O SDK for Java também fornece um modelo de persistência de objetos que permite que você mapeie suas classes do lado do cliente para tabelas do DynamoDB. Essa abordagem pode reduzir a quantidade de código que você precisa escrever. Para obter mais informações, consulte [Java 1.x: DynamoDBMapper](DynamoDBMapper.md).

**Topics**
+ [Exemplo: operação de gravação em lote usando a API de documento do AWS SDK para Java](#JavaDocumentAPIBatchWrite)
+ [Exemplo: operação de obtenção em lote usando a API de documento do AWS SDK para Java](#JavaDocumentAPIBatchGet)

## Exemplo: operação de gravação em lote usando a API de documento do AWS SDK para Java
<a name="JavaDocumentAPIBatchWrite"></a>

O exemplo de código Java a seguir usa o método `batchWriteItem` para executar as operações Put e Delete a seguir:
+ Inserir um item na tabela `Forum`.
+ Inserir e excluir um item da tabela `Thread`. 

Você pode especificar quantas solicitações de inserção e exclusão desejar em uma ou mais tabelas ao criar sua solicitação de gravação em lote. No entanto, `batchWriteItem` limita o tamanho de uma solicitação de gravação em lote e o número de operações Put e Delete em uma única operação. Se a sua solicitação ultrapassar esses limites, ela será rejeitada. Se a sua tabela não tiver throughput provisionado suficiente para servir a essa solicitação, os itens de solicitação não processados serão retornados na resposta. 

O exemplo a seguir verifica a resposta para conferir se existem itens de solicitação não processados. Se houver, ele retorna e reenvia a solicitação `batchWriteItem` com itens não processados na solicitação. Se você tiver seguido os exemplos neste guia, já deverá ter criado as tabelas `Forum` e `Thread`. Você também pode criar essas tabelas e fazer upload dos dados de exemplo de forma programática. Para obter mais informações, consulte [Criar exemplos de tabelas e carregar dados usando o AWS SDK para Java](AppendixSampleDataCodeJava.md).

Para obter instruções detalhadas sobre como testar o exemplo a seguir, consulte [Exemplos de código Java](CodeSamples.Java.md). 

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchWriteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableWriteItems;
import com.amazonaws.services.dynamodbv2.model.WriteRequest;

public class DocumentAPIBatchWrite {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {

        writeMultipleItemsBatchWrite();

    }

    private static void writeMultipleItemsBatchWrite() {
        try {

            // Add a new item to Forum
            TableWriteItems forumTableWriteItems = new TableWriteItems(forumTableName) // Forum
                    .withItemsToPut(new Item().withPrimaryKey("Name", "Amazon RDS").withNumber("Threads", 0));

            // Add a new item, and delete an existing item, from Thread
            // This table has a partition key and range key, so need to specify
            // both of them
            TableWriteItems threadTableWriteItems = new TableWriteItems(threadTableName)
                    .withItemsToPut(
                            new Item().withPrimaryKey("ForumName", "Amazon RDS", "Subject", "Amazon RDS Thread 1")
                                    .withString("Message", "ElastiCache Thread 1 message")
                                    .withStringSet("Tags", new HashSet<String>(Arrays.asList("cache", "in-memory"))))
                    .withHashAndRangeKeysToDelete("ForumName", "Subject", "Amazon S3", "S3 Thread 100");

            System.out.println("Making the request.");
            BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

            do {

                // Check for unprocessed keys which could happen if you exceed
                // provisioned throughput

                Map<String, List<WriteRequest>> unprocessedItems = outcome.getUnprocessedItems();

                if (outcome.getUnprocessedItems().size() == 0) {
                    System.out.println("No unprocessed items found");
                } else {
                    System.out.println("Retrieving the unprocessed items");
                    outcome = dynamoDB.batchWriteItemUnprocessed(unprocessedItems);
                }

            } while (outcome.getUnprocessedItems().size() > 0);

        } catch (Exception e) {
            System.err.println("Failed to retrieve items: ");
            e.printStackTrace(System.err);
        }

    }

}
```

## Exemplo: operação de obtenção em lote usando a API de documento do AWS SDK para Java
<a name="JavaDocumentAPIBatchGet"></a>

O exemplo de código Java a seguir usa o método `batchGetItem` para recuperar vários itens das tabelas `Forum` e `Thread`. A `BatchGetItemRequest` especifica os nomes de tabela e uma lista de chaves de cada item a ser obtido. O exemplo processa a resposta, imprimindo os itens recuperados.

**nota**  
Este exemplo de código pressupõe que você já carregou dados no DynamoDB para sua conta seguindo as instruções na seção [Criar tabelas e carregar dados para exemplos de código no DynamoDB](SampleData.md).  
Para obter instruções passo a passo sobre como executar o exemplo a seguir, consulte [Exemplos de código Java](CodeSamples.Java.md).

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchGetItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableKeysAndAttributes;
import com.amazonaws.services.dynamodbv2.model.KeysAndAttributes;

public class DocumentAPIBatchGet {
    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {
        retrieveMultipleItemsBatchGet();
    }

    private static void retrieveMultipleItemsBatchGet() {

        try {

            TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
            // Add a partition key
            forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB");

            TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
            // Add a partition key and a sort key
            threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB",
                    "DynamoDB Thread 1", "Amazon DynamoDB", "DynamoDB Thread 2", "Amazon S3", "S3 Thread 1");

            System.out.println("Making the request.");

            BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes,
                    threadTableKeysAndAttributes);

            Map<String, KeysAndAttributes> unprocessed = null;

            do {
                for (String tableName : outcome.getTableItems().keySet()) {
                    System.out.println("Items in table " + tableName);
                    List<Item> items = outcome.getTableItems().get(tableName);
                    for (Item item : items) {
                        System.out.println(item.toJSONPretty());
                    }
                }

                // Check for unprocessed keys which could happen if you exceed
                // provisioned
                // throughput or reach the limit on response size.
                unprocessed = outcome.getUnprocessedKeys();

                if (unprocessed.isEmpty()) {
                    System.out.println("No unprocessed keys found");
                } else {
                    System.out.println("Retrieving the unprocessed keys");
                    outcome = dynamoDB.batchGetItemUnprocessed(unprocessed);
                }

            } while (!unprocessed.isEmpty());

        } catch (Exception e) {
            System.err.println("Failed to retrieve items.");
            System.err.println(e.getMessage());
        }

    }

}
```

# Exemplo: tratar atributos do tipo binário usando a API de documento do AWS SDK para Java
<a name="JavaDocumentAPIBinaryTypeExample"></a>

O exemplo de código Java a seguir ilustra o tratamento de atributos do tipo binário. O exemplo adiciona um item à tabela `Reply`. O item inclui um atributo do tipo binário (`ExtendedMessage`) que armazena dados compactados. Em seguida, o exemplo recupera um item e imprime todos os valores do atributo. Para ilustração, o exemplo usa a classe `GZIPOutputStream` para compactar um stream de exemplo e atribuí-lo ao atributo `ExtendedMessage`. Quando o atributo binário é recuperado, ele é descompactado usando a classe `GZIPInputStream`. 

**nota**  
O SDK for Java também fornece um modelo de persistência de objetos que permite que você mapeie suas classes do lado do cliente para tabelas do DynamoDB. Essa abordagem pode reduzir a quantidade de código que você precisa escrever. Para obter mais informações, consulte [Java 1.x: DynamoDBMapper](DynamoDBMapper.md).

Se você tiver seguido a seção [Criar tabelas e carregar dados para exemplos de código no DynamoDB](SampleData.md), já deverá ter criado a tabela `Reply`. Você também pode criar essa tabela de forma programática. Para obter mais informações, consulte [Criar exemplos de tabelas e carregar dados usando o AWS SDK para Java](AppendixSampleDataCodeJava.md).

Para obter instruções detalhadas sobre como testar o exemplo a seguir, consulte [Exemplos de código Java](CodeSamples.Java.md). 

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.spec.GetItemSpec;

public class DocumentAPIItemBinaryExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String tableName = "Reply";
    static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    public static void main(String[] args) throws IOException {
        try {

            // Format the primary key values
            String threadId = "Amazon DynamoDB#DynamoDB Thread 2";

            dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
            String replyDateTime = dateFormatter.format(new Date());

            // Add a new reply with a binary attribute type
            createItem(threadId, replyDateTime);

            // Retrieve the reply with a binary attribute type
            retrieveItem(threadId, replyDateTime);

            // clean up by deleting the item
            deleteItem(threadId, replyDateTime);
        } catch (Exception e) {
            System.err.println("Error running the binary attribute type example: " + e);
            e.printStackTrace(System.err);
        }
    }

    public static void createItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        // Craft a long message
        String messageInput = "Long message to be compressed in a lengthy forum reply";

        // Compress the long message
        ByteBuffer compressedMessage = compressString(messageInput.toString());

        table.putItem(new Item().withPrimaryKey("Id", threadId).withString("ReplyDateTime", replyDateTime)
                .withString("Message", "Long message follows").withBinary("ExtendedMessage", compressedMessage)
                .withString("PostedBy", "User A"));
    }

    public static void retrieveItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        GetItemSpec spec = new GetItemSpec().withPrimaryKey("Id", threadId, "ReplyDateTime", replyDateTime)
                .withConsistentRead(true);

        Item item = table.getItem(spec);

        // Uncompress the reply message and print
        String uncompressed = uncompressString(ByteBuffer.wrap(item.getBinary("ExtendedMessage")));

        System.out.println("Reply message:\n" + " Id: " + item.getString("Id") + "\n" + " ReplyDateTime: "
                + item.getString("ReplyDateTime") + "\n" + " PostedBy: " + item.getString("PostedBy") + "\n"
                + " Message: "
                + item.getString("Message") + "\n" + " ExtendedMessage (uncompressed): " + uncompressed + "\n");
    }

    public static void deleteItem(String threadId, String replyDateTime) {

        Table table = dynamoDB.getTable(tableName);
        table.deleteItem("Id", threadId, "ReplyDateTime", replyDateTime);
    }

    private static ByteBuffer compressString(String input) throws IOException {
        // Compress the UTF-8 encoded String into a byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream os = new GZIPOutputStream(baos);
        os.write(input.getBytes("UTF-8"));
        os.close();
        baos.close();
        byte[] compressedBytes = baos.toByteArray();

        // The following code writes the compressed bytes to a ByteBuffer.
        // A simpler way to do this is by simply calling
        // ByteBuffer.wrap(compressedBytes);
        // However, the longer form below shows the importance of resetting the
        // position of the buffer
        // back to the beginning of the buffer if you are writing bytes directly
        // to it, since the SDK
        // will consider only the bytes after the current position when sending
        // data to DynamoDB.
        // Using the "wrap" method automatically resets the position to zero.
        ByteBuffer buffer = ByteBuffer.allocate(compressedBytes.length);
        buffer.put(compressedBytes, 0, compressedBytes.length);
        buffer.position(0); // Important: reset the position of the ByteBuffer
                            // to the beginning
        return buffer;
    }

    private static String uncompressString(ByteBuffer input) throws IOException {
        byte[] bytes = input.array();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPInputStream is = new GZIPInputStream(bais);

        int chunkSize = 1024;
        byte[] buffer = new byte[chunkSize];
        int length = 0;
        while ((length = is.read(buffer, 0, chunkSize)) != -1) {
            baos.write(buffer, 0, length);
        }

        String result = new String(baos.toByteArray(), "UTF-8");

        is.close();
        baos.close();
        bais.close();

        return result;
    }
}
```

# Trabalhar com itens: .NET
<a name="LowLevelDotNetItemCRUD"></a>

Você pode usar a API de baixo nível do AWS SDK para .NET para executar operações típicas create, read, update, delete (CRUD - criação, leitura, atualização e exclusão) em um item de uma tabela. Veja a seguir as etapas comuns que você segue para executar operações CRUD em dados usando a API de baixo nível do .NET:

1. Crie uma instância da classe `AmazonDynamoDBClient` (o cliente).

1. Forneça os parâmetros necessários específicos à operação em um objeto de solicitação correspondente.

   Por exemplo, use o objeto de solicitação `PutItemRequest` ao carregar um item e use o objeto de solicitação `GetItemRequest` ao recuperar um item existente. 

   Você pode usar o objeto de solicitação para fornecer tanto parâmetros necessários quanto opcionais. 

1. Execute o método apropriado fornecido pelo cliente, transmitindo o objeto de solicitação que você criou na etapa anterior. 

   O cliente `AmazonDynamoDBClient` fornece os métodos `PutItem`, `GetItem`, `UpdateItem` e `DeleteItem` para as operações CRUD.

**Topics**
+ [Colocar um item](#PutItemLowLevelAPIDotNet)
+ [Obter um item](#GetItemLowLevelDotNET)
+ [Atualizar um item](#UpdateItemLowLevelDotNet)
+ [Contador atômico](#AtomicCounterLowLevelDotNet)
+ [Excluir um item](#DeleteMidLevelDotNet)
+ [Gravação em lote: colocar e excluir vários itens](#BatchWriteLowLevelDotNet)
+ [Obtenção em lote: obter vários itens](#BatchGetLowLevelDotNet)
+ [Exemplo: operações CRUD usando a API de baixo nível AWS SDK para .NET](LowLevelDotNetItemsExample.md)
+ [Exemplo: operações em lote usando a API de baixo nível do AWS SDK para .NET](batch-operation-lowlevel-dotnet.md)
+ [Exemplo: tratar atributos do tipo binário usando a API de baixo nível do AWS SDK para .NET](LowLevelDotNetBinaryTypeExample.md)

## Colocar um item
<a name="PutItemLowLevelAPIDotNet"></a>

O método `PutItem` carrega um item em uma tabela. Se o item existe, ele substitui o item inteiro.

**nota**  
Em vez de substituir o item inteiro, se você quiser atualizar apenas atributos específicos, use o método `UpdateItem`. Para obter mais informações, consulte [Atualizar um item](#UpdateItemLowLevelDotNet).

Veja a seguir as etapas para carregar um item usando a API do SDK do .NET de baixo nível:

1. Crie uma instância da classe `AmazonDynamoDBClient`.

1. Forneça os parâmetros necessários, criando uma instância da classe `PutItemRequest`.

   Para inserir item, você deve fornecer o nome da tabela e o item. 

1. Execute o método `PutItem` fornecendo o objeto `PutItemRequest` que você criou na etapa anterior.

O exemplo de C\$1 a seguir demonstra as etapas anteriores. O exemplo faz upload de um item para a tabela `ProductCatalog`.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new PutItemRequest
{
   TableName = tableName,
   Item = new Dictionary<string, AttributeValue>()
      {
          { "Id", new AttributeValue { N = "201" }},
          { "Title", new AttributeValue { S = "Book 201 Title" }},
          { "ISBN", new AttributeValue { S = "11-11-11-11" }},
          { "Price", new AttributeValue { S = "20.00" }},
          {
            "Authors",
            new AttributeValue
            { SS = new List<string>{"Author1", "Author2"}   }
          }
      }
};
client.PutItem(request);
```

No exemplo anterior, você faz upload de um item de livro que tem os atributos `Id`, `Title`, `ISBN` e `Authors`. Observe que `Id` é um atributo de tipo numérico, e todos os outros atributos são do tipo string. Autores é um conjunto `String`.

### Especificar parâmetros opcionais
<a name="PutItemLowLevelAPIDotNetOptions"></a>

Você também pode fornecer parâmetros opcionais usando o objeto `PutItemRequest`, conforme mostrado no seguinte exemplo de C\$1. O exemplo especifica os seguintes parâmetros opcionais:
+ `ExpressionAttributeNames`, `ExpressionAttributeValues` e `ConditionExpression` especificam que o item pode ser substituído somente se o item existente tiver o atributo ISBN com um valor específico.
+ `ReturnValues`o parâmetro para solicitar o item antigo na resposta.

**Example**  

```
var request = new PutItemRequest
 {
   TableName = tableName,
   Item = new Dictionary<string, AttributeValue>()
               {
                   { "Id", new AttributeValue { N = "104" }},
                   { "Title", new AttributeValue { S = "Book 104  Title" }},
                   { "ISBN", new AttributeValue { S = "444-4444444444" }},
                   { "Authors",
                     new AttributeValue { SS = new List<string>{"Author3"}}}
               },
    // Optional parameters.
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#I", "ISBN"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":isbn",new AttributeValue {S = "444-4444444444"}}
    },
    ConditionExpression = "#I = :isbn"

};
var response = client.PutItem(request);
```

Para obter mais informações, consulte [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html).

## Obter um item
<a name="GetItemLowLevelDotNET"></a>

O método `GetItem` recupera um item.

**nota**  
Para recuperar vários itens, você pode usar o método `BatchGetItem`. Para obter mais informações, consulte [Obtenção em lote: obter vários itens](#BatchGetLowLevelDotNet).

Veja a seguir as etapas para recuperar um item existente usando a API do AWS SDK para .NET de baixo nível.

1. Crie uma instância da classe `AmazonDynamoDBClient`.

1. Forneça os parâmetros necessários, criando uma instância da classe `GetItemRequest`.

   Para obter um item, você deve fornecer o nome da tabela e a chave primária desse item. 

1. Execute o método `GetItem` fornecendo o objeto `GetItemRequest` que você criou na etapa anterior.

O exemplo de C\$1 a seguir demonstra as etapas anteriores. O exemplo recupera um item da tabela `ProductCatalog`.

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new GetItemRequest
 {
   TableName = tableName,
   Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
 };
 var response = client.GetItem(request);

// Check the response.
var result = response.GetItemResult;
var attributeMap = result.Item; // Attribute list in the response.
```

### Especificar parâmetros opcionais
<a name="GetItemLowLevelDotNETOptions"></a>

Você também pode fornecer parâmetros opcionais usando o objeto `GetItemRequest`, conforme mostrado no seguinte exemplo de C\$1. O exemplo especifica os parâmetros opcionais a seguir:
+ `ProjectionExpression`o parâmetro para especificar os atributos a serem recuperados.
+ `ConsistentRead`o parâmetro para realizar uma leitura fortemente consistente. Para saber mais sobre a consistência de leitura, consulte [Consistência de leitura do DynamoDB](HowItWorks.ReadConsistency.md).

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new GetItemRequest
 {
   TableName = tableName,
   Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
   // Optional parameters.
   ProjectionExpression = "Id, ISBN, Title, Authors",
   ConsistentRead = true
 };

 var response = client.GetItem(request);

// Check the response.
var result = response.GetItemResult;
var attributeMap = result.Item;
```

Para obter mais informações, consulte [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html).

## Atualizar um item
<a name="UpdateItemLowLevelDotNet"></a>

O método `UpdateItem` atualiza um item existente, se estiver presente. É possível usar a operação `UpdateItem` para atualizar valores de atributos existentes, adicionar novos atributos ou excluir atributos da coleção existente. Se o item que tem a chave primária especificada não for encontrado, ela adicionará um novo item.

A operação `UpdateItem` usa as seguintes diretrizes:
+ Se o item não existir, o `UpdateItem` adicionará um novo item usando a chave primária especificada na entrada.
+ Se o item existir, o `UpdateItem` aplicará as atualizações da seguinte maneira:
  + Substitui os valores de atributos existentes pelos valores na atualização.
  + Se o atributo que você fornecer na entrada não existir, ele adicionará um novo atributo ao item.
  + Se o valor do atributo de entrada for nulo, ele excluirá o atributo, se estiver presente. 
  + Se você usar `ADD` para a `Action`, poderá adicionar valores a um conjunto existente (conjunto de strings ou números) ou adicionar (usar um número positivo) ou subtrair (usar um número negativo) matematicamente com base no valor de atributo numérico existente.

**nota**  
A operação `PutItem` também pode realizar uma atualização. Para obter mais informações, consulte [Colocar um item](#PutItemLowLevelAPIDotNet). Por exemplo, se você chamar `PutItem` para fazer upload de um item, e a chave primária existir, a operação `PutItem` substituirá o item inteiro. Se houver atributos no item existente e esses atributos não forem especificados na entrada, a operação `PutItem` os excluirá. No entanto, `UpdateItem` só atualiza os atributos de entrada especificados. Outros atributos existentes desse item permanecerão inalterados. 

Veja a seguir as etapas para atualizar um item existente usando a API do SDK do .NET de baixo nível:

1. Crie uma instância da classe `AmazonDynamoDBClient`.

1. Forneça os parâmetros necessários, criando uma instância da classe `UpdateItemRequest`.

   Este é o objeto de solicitação em que você descreve todas as atualizações, por exemplo, adiciona atributos, atualizar atributos existentes ou excluir atributos. Para excluir um atributo existente, especifique o nome desse atributo com um valor nulo. 

1. Execute o método `UpdateItem` fornecendo o objeto `UpdateItemRequest` que você criou na etapa anterior. 

O exemplo de código C\$1 a seguir demonstra as etapas anteriores. O exemplo de código atualiza um item na tabela `ProductCatalog`. Ele adiciona um novo autor à coleção `Authors` e exclui o atributo `ISBN` existente. Ele também reduz o preço por um.



```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#A", "Authors"},
        {"#P", "Price"},
        {"#NA", "NewAttribute"},
        {"#I", "ISBN"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":auth",new AttributeValue { SS = {"Author YY","Author ZZ"}}},
        {":p",new AttributeValue {N = "1"}},
        {":newattr",new AttributeValue {S = "someValue"}},
    },

    // This expression does the following:
    // 1) Adds two new authors to the list
    // 2) Reduces the price
    // 3) Adds a new attribute to the item
    // 4) Removes the ISBN attribute from the item
    UpdateExpression = "ADD #A :auth SET #P = #P - :p, #NA = :newattr REMOVE #I"
};
var response = client.UpdateItem(request);
```

### Especificar parâmetros opcionais
<a name="UpdateItemLowLevelDotNETOptions"></a>

Você também pode fornecer parâmetros opcionais usando o objeto `UpdateItemRequest`, conforme mostrado no seguinte exemplo de C\$1. Especifica os parâmetros opcionais a seguir:
+ `ExpressionAttributeValues` e `ConditionExpression` para especificar que o preço apenas poderá ser atualizado se o preço existente for 20,00.
+ `ReturnValues`o parâmetro para solicitar o item atualizado na resposta. 

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },

    // Update price only if the current price is 20.00.
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#P", "Price"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":newprice",new AttributeValue {N = "22"}},
        {":currprice",new AttributeValue {N = "20"}}
    },
    UpdateExpression = "SET #P = :newprice",
    ConditionExpression = "#P = :currprice",
    TableName = tableName,
    ReturnValues = "ALL_NEW" // Return all the attributes of the updated item.
};

var response = client.UpdateItem(request);
```

Para obter mais informações, consulte [UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html). 

## Contador atômico
<a name="AtomicCounterLowLevelDotNet"></a>

Você pode usar `updateItem` para implementar um contador atômico, onde pode aumentar ou reduzir o valor de um atributo existente sem interferir em outras solicitações de gravação. Para atualizar um contador atômico, use `updateItem` com um atributo do tipo `Number` no parâmetro `UpdateExpression` e `ADD` como a `Action`.

O exemplo de código a seguir demonstra isso incrementando o atributo `Quantity` em um.

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "121" } } },
    ExpressionAttributeNames = new Dictionary<string, string>()
    {
        {"#Q", "Quantity"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":incr",new AttributeValue {N = "1"}}
    },
    UpdateExpression = "SET #Q = #Q + :incr",
    TableName = tableName
};

var response = client.UpdateItem(request);
```

## Excluir um item
<a name="DeleteMidLevelDotNet"></a>

O método `DeleteItem` exclui um item de uma tabela. 

Veja a seguir as etapas para excluir um item usando a API de SDK do .NET de baixo nível. 

1. Crie uma instância da classe `AmazonDynamoDBClient`.

1. Forneça os parâmetros necessários, criando uma instância da classe `DeleteItemRequest`.

    Para excluir um item, o nome da tabela e a chave primária desse item são necessários. 

1. Execute o método `DeleteItem` fornecendo o objeto `DeleteItemRequest` que você criou na etapa anterior. 

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new DeleteItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "201" } } },
};

var response = client.DeleteItem(request);
```

### Especificar parâmetros opcionais
<a name="DeleteItemLowLevelDotNETOptions"></a>

Você também pode fornecer parâmetros opcionais usando o objeto `DeleteItemRequest`, conforme mostrado no seguinte exemplo de código C\$1. Especifica os parâmetros opcionais a seguir:
+ `ExpressionAttributeValues` e `ConditionExpression` para especificar que o item de livro apenas poderá ser excluído se não estiver mais em publicação (se o valor do atributo InPublication for false). 
+ `ReturnValues`o parâmetro para solicitar o item excluído na resposta.

**Example**  

```
var request = new DeleteItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "201" } } },

    // Optional parameters.
    ReturnValues = "ALL_OLD",
    ExpressionAttributeNames = new Dictionary<string, string>()
    {
        {"#IP", "InPublication"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":inpub",new AttributeValue {BOOL = false}}
    },
    ConditionExpression = "#IP = :inpub"
};

var response = client.DeleteItem(request);
```

Para obter mais informações, consulte [DeleteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html).

## Gravação em lote: colocar e excluir vários itens
<a name="BatchWriteLowLevelDotNet"></a>

*Gravação em lote* se refere a inserir e excluir vários itens em um lote. O método `BatchWriteItem` permite que você insira e exclua vários itens de uma ou mais tabelas em uma única chamada. Veja a seguir as etapas para recuperar vários itens usando a API de SDK do .NET de baixo nível.

1. Crie uma instância da classe `AmazonDynamoDBClient`.

1. Descreva todas as operações de inserção e exclusão, criando uma instância da classe `BatchWriteItemRequest`.

1. Execute o método `BatchWriteItem` fornecendo o objeto `BatchWriteItemRequest` que você criou na etapa anterior.

1. Processe a resposta. Você deve verificar se há itens de solicitação não processados retornados na resposta. Isso poderá acontecer se você atingir a cota de throughput provisionado ou por algum outro erro temporário. Além disso, o DynamoDB limita o tamanho da solicitação e o número de operações que você pode especificar em uma solicitação. Se você exceder esses limites, o DynamoDB rejeitará a solicitação. Para obter mais informações, consulte [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html). 

O exemplo de código C\$1 a seguir demonstra as etapas anteriores. O exemplo cria uma `BatchWriteItemRequest` para realizar as seguintes operações de gravação:
+ Inserir um item na tabela `Forum`.
+ Inserir e excluir um item da tabela `Thread`.

Em seguida, o código executa `BatchWriteItem` para realizar uma operação em lote.

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";
string table2Name = "Thread";

var request = new BatchWriteItemRequest
 {
   RequestItems = new Dictionary<string, List<WriteRequest>>
    {
      {
        table1Name, new List<WriteRequest>
        {
          new WriteRequest
          {
             PutRequest = new PutRequest
             {
                Item = new Dictionary<string,AttributeValue>
                {
                  { "Name", new AttributeValue { S = "Amazon S3 forum" } },
                  { "Threads", new AttributeValue { N = "0" }}
                }
             }
          }
        }
      } ,
      {
        table2Name, new List<WriteRequest>
        {
          new WriteRequest
          {
            PutRequest = new PutRequest
            {
               Item = new Dictionary<string,AttributeValue>
               {
                 { "ForumName", new AttributeValue { S = "Amazon S3 forum" } },
                 { "Subject", new AttributeValue { S = "My sample question" } },
                 { "Message", new AttributeValue { S = "Message Text." } },
                 { "KeywordTags", new AttributeValue { SS = new List<string> { "Amazon S3", "Bucket" }  } }
               }
            }
          },
          new WriteRequest
          {
             DeleteRequest = new DeleteRequest
             {
                Key = new Dictionary<string,AttributeValue>()
                {
                   { "ForumName", new AttributeValue { S = "Some forum name" } },
                   { "Subject", new AttributeValue { S = "Some subject" } }
                }
             }
          }
        }
      }
    }
 };
response = client.BatchWriteItem(request);
```

Para obter um exemplo funcional, consulte [Exemplo: operações em lote usando a API de baixo nível do AWS SDK para .NET](batch-operation-lowlevel-dotnet.md). 

## Obtenção em lote: obter vários itens
<a name="BatchGetLowLevelDotNet"></a>

O método `BatchGetItem` permite que você recupere vários itens de uma ou mais tabelas. 

**nota**  
Para recuperar um único item, você pode usar o método `GetItem`. 

Veja a seguir as etapas para recuperar vários itens usando a API do AWS SDK para .NET de baixo nível.

1. Crie uma instância da classe `AmazonDynamoDBClient`.

1. Forneça os parâmetros necessários, criando uma instância da classe `BatchGetItemRequest`.

   Para recuperar vários itens, o nome da tabela e uma lista de valores de chave primária são necessários. 

1. Execute o método `BatchGetItem` fornecendo o objeto `BatchGetItemRequest` que você criou na etapa anterior.

1. Processe a resposta. Você deve verificar se houve chaves não processadas, o que pode acontecer caso você tenha atingido a cota de throughput provisionado ou caso tenha ocorrido algum outro erro temporário.

O exemplo de código C\$1 a seguir demonstra as etapas anteriores. O exemplo recupera itens de duas tabelas, `Forum` e `Thread`. A solicitação especifica dois itens na tabela `Forum` e três itens em `Thread`. A resposta inclui itens de ambas as tabelas. O código mostra como você pode processar a resposta.



```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";
string table2Name = "Thread";

var request = new BatchGetItemRequest
{
  RequestItems = new Dictionary<string, KeysAndAttributes>()
  {
    { table1Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "DynamoDB" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "Amazon S3" } }
          }
        }
      }
    },
    {
      table2Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "DynamoDB" } },
            { "Subject", new AttributeValue { S = "DynamoDB Thread 1" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "DynamoDB" } },
            { "Subject", new AttributeValue { S = "DynamoDB Thread 2" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "Amazon S3" } },
            { "Subject", new AttributeValue { S = "Amazon S3 Thread 1" } }
          }
        }
      }
    }
  }
};

var response = client.BatchGetItem(request);

// Check the response.
var result = response.BatchGetItemResult;
var responses = result.Responses; // The attribute list in the response.

var table1Results = responses[table1Name];
Console.WriteLine("Items in table {0}" + table1Name);
foreach (var item1 in table1Results.Items)
{
  PrintItem(item1);
}

var table2Results = responses[table2Name];
Console.WriteLine("Items in table {1}" + table2Name);
foreach (var item2 in table2Results.Items)
{
  PrintItem(item2);
}
// Any unprocessed keys? could happen if you exceed ProvisionedThroughput or some other error.
Dictionary<string, KeysAndAttributes> unprocessedKeys = result.UnprocessedKeys;
foreach (KeyValuePair<string, KeysAndAttributes> pair in unprocessedKeys)
{
    Console.WriteLine(pair.Key, pair.Value);
}
```



### Especificar parâmetros opcionais
<a name="BatchGetItemLowLevelDotNETOptions"></a>

Você também pode fornecer parâmetros opcionais usando o objeto `BatchGetItemRequest`, conforme mostrado no seguinte exemplo de código C\$1. O exemplo recupera dois itens da tabela `Forum`. Ele especifica o parâmetro opcional a seguir:
+  `ProjectionExpression`o parâmetro para especificar os atributos a serem recuperados.

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";

var request = new BatchGetItemRequest
{
  RequestItems = new Dictionary<string, KeysAndAttributes>()
  {
    { table1Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "DynamoDB" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "Amazon S3" } }
          }
        }
      },
      // Optional - name of an attribute to retrieve.
      ProjectionExpression = "Title"
    }
  }
};

var response = client.BatchGetItem(request);
```

Para obter mais informações, consulte [BatchGetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html). 

# Exemplo: operações CRUD usando a API de baixo nível AWS SDK para .NET
<a name="LowLevelDotNetItemsExample"></a>

O exemplo de código C\$1 a seguir ilustra operações CRUD em um item do Amazon DynamoDB. O exemplo adiciona um item à tabela `ProductCatalog`, recupera-o, executa várias atualizações e, por fim, exclui o item. Se você não criou essa tabela, também pode criá-la de maneira programática. Para obter mais informações, consulte [Criar exemplos de tabelas e carregar dados usando o AWS SDK para .NET](AppendixSampleDataCodeDotNET.md).

Para obter instruções detalhadas sobre como testar o exemplo a seguir, consulte [Exemplos de código .NET](CodeSamples.DotNet.md). 

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;
using Amazon.SecurityToken;

namespace com.amazonaws.codesamples
{
    class LowLevelItemCRUDExample
    {
        private static string tableName = "ProductCatalog";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                CreateItem();
                RetrieveItem();

                // Perform various updates.
                UpdateMultipleAttributes();
                UpdateExistingAttributeConditionally();

                // Delete item.
                DeleteItem();
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
        }

        private static void CreateItem()
        {
            var request = new PutItemRequest
            {
                TableName = tableName,
                Item = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  }},
                { "Title", new AttributeValue {
                      S = "Book 201 Title"
                  }},
                { "ISBN", new AttributeValue {
                      S = "11-11-11-11"
                  }},
                { "Authors", new AttributeValue {
                      SS = new List<string>{"Author1", "Author2" }
                  }},
                { "Price", new AttributeValue {
                      N = "20.00"
                  }},
                { "Dimensions", new AttributeValue {
                      S = "8.5x11.0x.75"
                  }},
                { "InPublication", new AttributeValue {
                      BOOL = false
                  } }
            }
            };
            client.PutItem(request);
        }

        private static void RetrieveItem()
        {
            var request = new GetItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                ProjectionExpression = "Id, ISBN, Title, Authors",
                ConsistentRead = true
            };
            var response = client.GetItem(request);

            // Check the response.
            var attributeList = response.Item; // attribute list in the response.
            Console.WriteLine("\nPrinting item after retrieving it ............");
            PrintItem(attributeList);
        }

        private static void UpdateMultipleAttributes()
        {
            var request = new UpdateItemRequest
            {
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                // Perform the following updates:
                // 1) Add two new authors to the list
                // 1) Set a new attribute
                // 2) Remove the ISBN attribute
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#A","Authors"},
                {"#NA","NewAttribute"},
                {"#I","ISBN"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":auth",new AttributeValue {
                     SS = {"Author YY", "Author ZZ"}
                 }},
                {":new",new AttributeValue {
                     S = "New Value"
                 }}
            },

                UpdateExpression = "ADD #A :auth SET #NA = :new REMOVE #I",

                TableName = tableName,
                ReturnValues = "ALL_NEW" // Give me all attributes of the updated item.
            };
            var response = client.UpdateItem(request);

            // Check the response.
            var attributeList = response.Attributes; // attribute list in the response.
                                                     // print attributeList.
            Console.WriteLine("\nPrinting item after multiple attribute update ............");
            PrintItem(attributeList);
        }

        private static void UpdateExistingAttributeConditionally()
        {
            var request = new UpdateItemRequest
            {
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#P", "Price"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":newprice",new AttributeValue {
                     N = "22.00"
                 }},
                {":currprice",new AttributeValue {
                     N = "20.00"
                 }}
            },
                // This updates price only if current price is 20.00.
                UpdateExpression = "SET #P = :newprice",
                ConditionExpression = "#P = :currprice",

                TableName = tableName,
                ReturnValues = "ALL_NEW" // Give me all attributes of the updated item.
            };
            var response = client.UpdateItem(request);

            // Check the response.
            var attributeList = response.Attributes; // attribute list in the response.
            Console.WriteLine("\nPrinting item after updating price value conditionally ............");
            PrintItem(attributeList);
        }

        private static void DeleteItem()
        {
            var request = new DeleteItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },

                // Return the entire item as it appeared before the update.
                ReturnValues = "ALL_OLD",
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#IP", "InPublication"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":inpub",new AttributeValue {
                     BOOL = false
                 }}
            },
                ConditionExpression = "#IP = :inpub"
            };

            var response = client.DeleteItem(request);

            // Check the response.
            var attributeList = response.Attributes; // Attribute list in the response.
                                                     // Print item.
            Console.WriteLine("\nPrinting item that was just deleted ............");
            PrintItem(attributeList);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }
    }
}
```

# Exemplo: operações em lote usando a API de baixo nível do AWS SDK para .NET
<a name="batch-operation-lowlevel-dotnet"></a>

**Topics**
+ [Exemplo: operação de gravação em lote usando a API de baixo nível do AWS SDK para .NET](#batch-write-low-level-dotnet)
+ [Exemplo: operação de obtenção em lote usando a API de baixo nível do AWS SDK para .NET](#LowLevelDotNetBatchGet)

Esta seção fornece exemplos de operações em lote, *gravação em lote* e *aquisição em lote* aceitas pelo Amazon DynamoDB.

## Exemplo: operação de gravação em lote usando a API de baixo nível do AWS SDK para .NET
<a name="batch-write-low-level-dotnet"></a>

O exemplo de código C\$1 a seguir usa o método `BatchWriteItem` para executar as operações de inserção e exclusão a seguir:
+ Inserir um item na tabela `Forum`.
+ Inserir e excluir um item da tabela `Thread`. 

Você pode especificar quantas solicitações de inserção e exclusão desejar em uma ou mais tabelas ao criar sua solicitação de gravação em lote. No entanto, `BatchWriteItem` do DynamoDB limita o tamanho de uma solicitação de gravação em lote e o número de operações Put e Delete em uma única operação. Para obter mais informações, consulte [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html). Se a sua solicitação ultrapassar esses limites, ela será rejeitada. Se a sua tabela não tiver throughput provisionado suficiente para servir a essa solicitação, os itens de solicitação não processados serão retornados na resposta. 

O exemplo a seguir verifica a resposta para conferir se existem itens de solicitação não processados. Se houver, ele retorna e reenvia a solicitação `BatchWriteItem` com itens não processados na solicitação. Você também pode criar essas tabelas de exemplo e carregar dados de exemplo de forma programática. Para obter mais informações, consulte [Criar exemplos de tabelas e carregar dados usando o AWS SDK para .NET](AppendixSampleDataCodeDotNET.md).

Para obter instruções detalhadas sobre como testar o exemplo a seguir, consulte [Exemplos de código .NET](CodeSamples.DotNet.md). 

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelBatchWrite
    {
        private static string table1Name = "Forum";
        private static string table2Name = "Thread";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                TestBatchWrite();
            }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }

            Console.WriteLine("To continue, press Enter");
            Console.ReadLine();
        }

        private static void TestBatchWrite()
        {
            var request = new BatchWriteItemRequest
            {
                ReturnConsumedCapacity = "TOTAL",
                RequestItems = new Dictionary<string, List<WriteRequest>>
            {
                {
                    table1Name, new List<WriteRequest>
                    {
                        new WriteRequest
                        {
                            PutRequest = new PutRequest
                            {
                                Item = new Dictionary<string, AttributeValue>
                                {
                                    { "Name", new AttributeValue {
                                          S = "S3 forum"
                                      } },
                                    { "Threads", new AttributeValue {
                                          N = "0"
                                      }}
                                }
                            }
                        }
                    }
                },
                {
                    table2Name, new List<WriteRequest>
                    {
                        new WriteRequest
                        {
                            PutRequest = new PutRequest
                            {
                                Item = new Dictionary<string, AttributeValue>
                                {
                                    { "ForumName", new AttributeValue {
                                          S = "S3 forum"
                                      } },
                                    { "Subject", new AttributeValue {
                                          S = "My sample question"
                                      } },
                                    { "Message", new AttributeValue {
                                          S = "Message Text."
                                      } },
                                    { "KeywordTags", new AttributeValue {
                                          SS = new List<string> { "S3", "Bucket" }
                                      } }
                                }
                            }
                        },
                        new WriteRequest
                        {
                            // For the operation to delete an item, if you provide a primary key value
                            // that does not exist in the table, there is no error, it is just a no-op.
                            DeleteRequest = new DeleteRequest
                            {
                                Key = new Dictionary<string, AttributeValue>()
                                {
                                    { "ForumName",  new AttributeValue {
                                          S = "Some partition key value"
                                      } },
                                    { "Subject", new AttributeValue {
                                          S = "Some sort key value"
                                      } }
                                }
                            }
                        }
                    }
                }
            }
            };

            CallBatchWriteTillCompletion(request);
        }

        private static void CallBatchWriteTillCompletion(BatchWriteItemRequest request)
        {
            BatchWriteItemResponse response;

            int callCount = 0;
            do
            {
                Console.WriteLine("Making request");
                response = client.BatchWriteItem(request);
                callCount++;

                // Check the response.

                var tableConsumedCapacities = response.ConsumedCapacity;
                var unprocessed = response.UnprocessedItems;

                Console.WriteLine("Per-table consumed capacity");
                foreach (var tableConsumedCapacity in tableConsumedCapacities)
                {
                    Console.WriteLine("{0} - {1}", tableConsumedCapacity.TableName, tableConsumedCapacity.CapacityUnits);
                }

                Console.WriteLine("Unprocessed");
                foreach (var unp in unprocessed)
                {
                    Console.WriteLine("{0} - {1}", unp.Key, unp.Value.Count);
                }
                Console.WriteLine();

                // For the next iteration, the request will have unprocessed items.
                request.RequestItems = unprocessed;
            } while (response.UnprocessedItems.Count > 0);

            Console.WriteLine("Total # of batch write API calls made: {0}", callCount);
        }
    }
}
```

## Exemplo: operação de obtenção em lote usando a API de baixo nível do AWS SDK para .NET
<a name="LowLevelDotNetBatchGet"></a>

O exemplo de código C\$1 a seguir usa o método `BatchGetItem` para recuperar vários itens das tabelas `Forum` e `Thread` no Amazon DynamoDB. A `BatchGetItemRequest` especifica os nomes de tabelas e uma lista de chaves primárias para cada tabela. O exemplo processa a resposta, imprimindo os itens recuperados. 

Para obter instruções detalhadas sobre como testar o exemplo a seguir, consulte [Exemplos de código .NET](CodeSamples.DotNet.md). 

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelBatchGet
    {
        private static string table1Name = "Forum";
        private static string table2Name = "Thread";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                RetrieveMultipleItemsBatchGet();

                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }

        private static void RetrieveMultipleItemsBatchGet()
        {
            var request = new BatchGetItemRequest
            {
                RequestItems = new Dictionary<string, KeysAndAttributes>()
            {
                { table1Name,
                  new KeysAndAttributes
                  {
                      Keys = new List<Dictionary<string, AttributeValue> >()
                      {
                          new Dictionary<string, AttributeValue>()
                          {
                              { "Name", new AttributeValue {
                            S = "Amazon DynamoDB"
                        } }
                          },
                          new Dictionary<string, AttributeValue>()
                          {
                              { "Name", new AttributeValue {
                            S = "Amazon S3"
                        } }
                          }
                      }
                  }},
                {
                    table2Name,
                    new KeysAndAttributes
                    {
                        Keys = new List<Dictionary<string, AttributeValue> >()
                        {
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon DynamoDB"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "DynamoDB Thread 1"
                                  } }
                            },
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon DynamoDB"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "DynamoDB Thread 2"
                                  } }
                            },
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon S3"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "S3 Thread 1"
                                  } }
                            }
                        }
                    }
                }
            }
            };

            BatchGetItemResponse response;
            do
            {
                Console.WriteLine("Making request");
                response = client.BatchGetItem(request);

                // Check the response.
                var responses = response.Responses; // Attribute list in the response.

                foreach (var tableResponse in responses)
                {
                    var tableResults = tableResponse.Value;
                    Console.WriteLine("Items retrieved from table {0}", tableResponse.Key);
                    foreach (var item1 in tableResults)
                    {
                        PrintItem(item1);
                    }
                }

                // Any unprocessed keys? could happen if you exceed ProvisionedThroughput or some other error.
                Dictionary<string, KeysAndAttributes> unprocessedKeys = response.UnprocessedKeys;
                foreach (var unprocessedTableKeys in unprocessedKeys)
                {
                    // Print table name.
                    Console.WriteLine(unprocessedTableKeys.Key);
                    // Print unprocessed primary keys.
                    foreach (var key in unprocessedTableKeys.Value.Keys)
                    {
                        PrintItem(key);
                    }
                }

                request.RequestItems = unprocessedKeys;
            } while (response.UnprocessedKeys.Count > 0);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }
    }
}
```

# Exemplo: tratar atributos do tipo binário usando a API de baixo nível do AWS SDK para .NET
<a name="LowLevelDotNetBinaryTypeExample"></a>

O exemplo de código C\$1 a seguir ilustra a manipulação de atributos do tipo Binário. O exemplo adiciona um item à tabela `Reply`. O item inclui um atributo do tipo binário (`ExtendedMessage`) que armazena dados compactados. Em seguida, o exemplo recupera um item e imprime todos os valores do atributo. Para ilustração, o exemplo usa a classe `GZipStream` para compactar um stream de exemplo e designá-lo ao atributo `ExtendedMessage`. Em seguida, ele descompacta esse stream ao imprimir o valor do atributo. 

Para obter instruções passo a passo sobre como testar o exemplo a seguir, consulte [Exemplos de código .NET](CodeSamples.DotNet.md). 

**Example**  

```
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelItemBinaryExample
    {
        private static string tableName = "Reply";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            // Reply table primary key.
            string replyIdPartitionKey = "Amazon DynamoDB#DynamoDB Thread 1";
            string replyDateTimeSortKey = Convert.ToString(DateTime.UtcNow);

            try
            {
                CreateItem(replyIdPartitionKey, replyDateTimeSortKey);
                RetrieveItem(replyIdPartitionKey, replyDateTimeSortKey);
                // Delete item.
                DeleteItem(replyIdPartitionKey, replyDateTimeSortKey);
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }

        private static void CreateItem(string partitionKey, string sortKey)
        {
            MemoryStream compressedMessage = ToGzipMemoryStream("Some long extended message to compress.");
            var request = new PutItemRequest
            {
                TableName = tableName,
                Item = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  }},
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  }},
                { "Subject", new AttributeValue {
                      S = "Binary type "
                  }},
                { "Message", new AttributeValue {
                      S = "Some message about the binary type"
                  }},
                { "ExtendedMessage", new AttributeValue {
                      B = compressedMessage
                  }}
            }
            };
            client.PutItem(request);
        }

        private static void RetrieveItem(string partitionKey, string sortKey)
        {
            var request = new GetItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  } },
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  } }
            },
                ConsistentRead = true
            };
            var response = client.GetItem(request);

            // Check the response.
            var attributeList = response.Item; // attribute list in the response.
            Console.WriteLine("\nPrinting item after retrieving it ............");

            PrintItem(attributeList);
        }

        private static void DeleteItem(string partitionKey, string sortKey)
        {
            var request = new DeleteItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  } },
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  } }
            }
            };
            var response = client.DeleteItem(request);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]") +
                    (value.B == null ? "" : "B=[" + FromGzipMemoryStream(value.B) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }

        private static MemoryStream ToGzipMemoryStream(string value)
        {
            MemoryStream output = new MemoryStream();
            using (GZipStream zipStream = new GZipStream(output, CompressionMode.Compress, true))
            using (StreamWriter writer = new StreamWriter(zipStream))
            {
                writer.Write(value);
            }
            return output;
        }

        private static string FromGzipMemoryStream(MemoryStream stream)
        {
            using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress))
            using (StreamReader reader = new StreamReader(zipStream))
            {
                return reader.ReadToEnd();
            }
        }
    }
}
```