Trabalhar com itens e atributos no DynamoDB
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 ter mais informações, consulte Amazon DynamoDB: como funciona.
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.
Tópicos
- Tamanhos e formatos de item do DynamoDB
- Ler um item
- Gravar um item
- Retornar valores
- Operações em lote
- Contadores atômicos
- Gravações condicionais
- Usar expressões no DynamoDB
- Usar a vida útil (TTL) no DynamoDB
- Consultar tabelas no DynamoDB
- Verificar tabelas no DynamoDB
- PartiQL: uma linguagem de consultas compatível com SQL para o Amazon DynamoDB
- Trabalhar com itens: Java
- Trabalhar com itens: .NET
Ler um item
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.
exemplo
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 ter mais informações, consulte Usar expressões de projeção no DynamoDB.
Para retornar o número de unidades de capacidade de leitura consumidas por GetItem
, defina o parâmetro ReturnConsumedCapacity
como TOTAL
.
exemplo
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
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
PutItem
cria um novo item. Se um item com a mesma chave já existir na tabela, ele será substituído pelo novo item.
exemplo
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
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 ter mais informações, consulte Usar expressões de atualização no DynamoDB.
Na expressão de atualização, use valores de atributos de expressão como espaços reservados para os valores reais. Para ter mais informações, consulte Usar valores de atributos de expressão no DynamoDB.
exemplo
Modifique vários atributos no item Thread
. O parâmetro opcional ReturnValues
mostra o item como ele aparece após a atualização. Para ter mais informações, consulte Retornar valores.
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
DeleteItem
exclui o item com a chave especificada.
exemplo
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
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
-
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
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
-
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
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
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.
exemplo
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 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
.
exemplo
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
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.
exemplo
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
Por padrão, as operações de gravação do DynamoDB (PutItem
, UpdateItem
, DeleteItem
) são incondicionais: cada operação substitui um item existente que possui 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.
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.
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 ter mais informações, consulte Exemplo de expressão de condição do DynamoDB na CLI.
Idempotência de gravação condicional
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
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.