Uso de elementos y atributos - Amazon DynamoDB

Uso de elementos y atributos

En Amazon DynamoDB, un elemento es una colección de atributos. Cada atributo tiene un nombre y un valor. Los valores de los atributos pueden ser escalares, conjuntos o tipos de documentos. Para obtener más información, consulte Funcionamiento de Amazon DynamoDB.

DynamoDB proporciona cuatro operaciones que aportan la funcionalidad básica de creación, lectura, actualización y eliminación (CRUD). Todas estas operaciones son atómicas.

  • PutItem: permite crear un elemento.

  • GetItem: permite leer un elemento.

  • UpdateItem: permite actualizar un elemento.

  • DeleteItem: permite eliminar un elemento.

Cada una de estas operaciones requiere que especifique la clave principal del elemento que se va a usar. Por ejemplo, para leer un elemento mediante GetItem, debe especificar la clave de partición y la clave de ordenación (si procede) de ese elemento.

Además de las cuatro operaciones CRUD básicas, DynamoDB también ofrece las siguientes:

  • BatchGetItem: permite leer hasta 100 elementos de una o varias tablas.

  • BatchWriteItem: permite crear o eliminar hasta 25 elementos en una o varias tablas.

Estas operaciones por lotes combinan varias operaciones CRUD en una sola solicitud. Además, las operaciones por lotes leen y escriben los elementos en paralelo, para minimizar las latencias de respuesta.

Esta sección se describe cómo utilizar estas operaciones y se incluyen los temas relacionados, tales como las actualizaciones condicionales y los contadores atómicas. Además, se facilitan ejemplos de código en los que se utilizan los SDK de AWS.

Lectura de un elemento

Para leer un elemento de una tabla de DynamoDB, se utiliza la operación GetItem. Debe proporcionar el nombre de la tabla, así como la clave principal del elemento que se desea.

ejemplo

En el siguiente ejemplo de la AWS CLI se muestra cómo leer un elemento de la tabla ProductCatalog.

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

Con GetItem, es preciso especificar la clave principal completa, no solo una parte de ella. Por ejemplo, si una tabla contiene una clave principal compuesta (clave de partición y clave de ordenación), tendrá que proporcionar un valor para la clave de partición y un valor para la clave de ordenación.

De forma predeterminada, una solicitud GetItem lleva a cabo una lectura consistente final. Puede usar el parámetro ConsistentRead para solicitar una lectura de consistencia alta, si lo prefiere. (Esto consume unidades de capacidad de lectura adicionales, pero devuelve la versión más actualizada del elemento).

GetItem devuelve todos los atributos del elemento. Puede usar una expresión de proyección para devolver solamente algunos de los atributos. Para obtener más información, consulte Expresiones de proyección.

Para devolver el número de unidades de capacidad de lectura consumidas por GetItem, establezca el parámetro ReturnConsumedCapacity en TOTAL.

ejemplo

En el siguiente ejemplo de la AWS Command Line Interface (AWS CLI) se muestran algunos de los parámetros de GetItem opcionales.

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

Escritura de un elemento

Para crear, actualizar o eliminar un elemento de una tabla de DynamoDB, utilice una de las siguientes operaciones:

  • PutItem

  • UpdateItem

  • DeleteItem

Para cada una de estas operaciones, debe especificar la clave principal completa, no solo parte de ella. Por ejemplo, si una tabla contiene una clave principal compuesta (clave de partición y clave de ordenación), tendrá que proporcionar un valor para la clave de partición y un valor para la clave de ordenación.

Para devolver el número de unidades de capacidad de escritura consumidas por cualquiera de estas operaciones, establezca el parámetro ReturnConsumedCapacity en uno de los valores siguientes:

  • TOTAL: devuelve el número total de unidades de capacidad de escritura consumidas.

  • INDEXES: devuelve el número total de unidades de capacidad de escritura consumidas, con subtotales para la tabla y todos los índices secundarios que se hayan visto afectados por la operación.

  • NONE: no devuelve ningún dato de capacidad de escritura consumida. (Esta es la opción predeterminada.)

PutItem

PutItem crea un elemento nuevo. Si ya existe un elemento con la misma clave en la tabla, se sustituirá por el nuevo.

ejemplo

Escriba un nuevo elemento en la tabla Thread. La clave principal de Thread consta de ForumName (clave de partición) y Subject (clave de ordenación).

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

Los argumentos de --item se almacenan en el archivo 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

Si no existe un elemento con la clave especificada, UpdateItem crea uno nuevo. De lo contrario, modifica los atributos de un elemento existente.

Se utiliza una expresión de actualización para especificar los atributos que se desea modificar y los nuevos valores. Para obtener más información, consulte Expresiones de actualización.

En la expresión de actualización, se utilizan valores de atributos de expresión como marcadores de posición de los valores reales. Para obtener más información, consulte Valores de los atributos de expresión.

ejemplo

Modifique varios atributos del elemento Thread. El parámetro ReturnValues opcional muestra el elemento tal y como aparece después de la actualización. Para obtener más información, consulte Valores de retorno:.

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

Los argumentos de --key se almacenan en el archivo key.json.

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

Los argumentos de --expression-attribute-values se almacenan en el archivo expression-attribute-values.json.

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

DeleteItem

DeleteItem elimina el elemento con la clave especificada.

ejemplo

En el ejemplo siguiente de la AWS CLI, se muestra cómo eliminar el elemento Thread.

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

Valores de retorno:

En algunos casos, es posible que desee que DynamoDB devuelva los valores de algunos atributos tal y como aparecen antes o después de modificarlos. Las operaciones PutItem, UpdateItem y DeleteItem tienen un parámetro ReturnValues que se puede usar para devolver los valores de los atributos antes o después de modificarlos.

El valor predeterminado de ReturnValues es NONE, es decir, DynamoDB no devuelve ninguna información sobre los atributos modificados.

A continuación se indican la otra configuración válida de ReturnValues, organizados según la operación de la API de DynamoDB.

PutItem

  • ReturnValues: ALL_OLD

    • Si sobrescribe un elemento existente, ALL_OLD devuelve el elemento completo tal y como aparecía antes de sobrescribirlo.

    • Si escribe un elemento que no existía, ALL_OLD no surte efecto.

UpdateItem

Lo más frecuente es usar UpdateItem para actualizar un elemento existente. Sin embargo, UpdateItem en realidad lleva a cabo una operación upsert (actualización/inserción). Esto quiere decir que creará el elemento automáticamente si este no existe.

  • ReturnValues: ALL_OLD

    • Si actualiza un elemento existente, ALL_OLD devuelve el elemento completo tal y como aparecía antes de actualizarlo.

    • Si actualiza un elemento que no existía (upsert), ALL_OLD no surte efecto.

  • ReturnValues: ALL_NEW

    • Si actualiza un elemento existente, ALL_NEW devuelve el elemento completo tal y como aparece después de actualizarlo.

    • Si actualiza un elemento que no existía (upsert), ALL_NEW devuelve el elemento completo.

  • ReturnValues: UPDATED_OLD

    • Si actualiza un elemento existente, UPDATED_OLD devuelve solamente los atributos actualizados, tal y como aparecían antes de la actualización.

    • Si actualiza un elemento que no existía (upsert), UPDATED_OLD no surte efecto.

  • ReturnValues: UPDATED_NEW

    • Si actualiza un elemento existente, UPDATED_NEW devuelve solamente los atributos afectados, tal y como aparecen después de la actualización.

    • Si actualiza un elemento que no existía (upsert), UPDATED_NEW devuelve solamente los atributos actualizados, tal y como aparecen después de la actualización.

DeleteItem

  • ReturnValues: ALL_OLD

    • Si elimina un elemento existente, ALL_OLD devuelve el elemento completo tal y como aparecía antes de eliminarlo.

    • Si elimina un elemento que no existía, ALL_OLD no devuelve ningún dato.

Operaciones por lotes

Para las aplicaciones que requieren leer o escribir varios elementos, DynamoDB proporciona las operaciones BatchGetItem y BatchWriteItem. El uso de estas operaciones puede reducir el número de recorridos de ida y vuelta a través de la red entre la aplicación y DynamoDB. Además, DynamoDB lleva a cabo las operaciones de lectura y escritura individuales en paralelo. Las aplicaciones se benefician de este procesamiento en paralelo sin tener que administrar la concurrencia ni los subprocesos.

En esencia, las operaciones por lotes son encapsuladores que incluyen varias solicitudes de lectura o escritura. Por ejemplo, si una solicitud BatchGetItem contiene cinco elementos, DynamoDB lleva a cabo cinco operaciones GetItem. De igual modo, si una solicitud BatchWriteItem contiene dos solicitudes de colocación y cuatro de eliminación, DynamoDB llevará a cabo dos solicitudes PutItem y cuatro solicitudes DeleteItem.

En general, una operación por lotes no genera un error a no ser que todas las solicitudes del lote generen un error. Por ejemplo, suponga que lleva a cabo una operación BatchGetItem, pero que se produce un error en una de las solicitudes GetItem individuales del lote. En este caso, BatchGetItem devolverá las claves y los datos de la solicitud GetItem en la que se ha producido el error. Las demás solicitudes GetItem del lote no se ven afectadas.

BatchGetItem

Una sola operación BatchGetItem puede contener hasta 100 solicitudes GetItem individuales y recuperar hasta 16 MB de datos. Además, una operación BatchGetItem puede recuperar elementos de varias tablas.

ejemplo

Recupere dos elementos de la tabla Thread usando una expresión de proyección para devolver solo algunos de los atributos.

aws dynamodb batch-get-item \ --request-items file://request-items.json

Los argumentos de --request-items se almacenan en el archivo 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

La operación BatchWriteItem puede contener hasta 25 solicitudes PutItem y DeleteItem individuales y puede escribir hasta 16 MB de datos. (El tamaño máximo de un elemento individual es de 400 KB). Además, una operación BatchWriteItem puede colocar o eliminar elementos en varias tablas.

nota

BatchWriteItem no admite las solicitudes UpdateItem.

ejemplo

Escriba dos elementos en la tabla ProductCatalog.

aws dynamodb batch-write-item \ --request-items file://request-items.json

Los argumentos de --request-items se almacenan en el archivo 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

Puede usar la operación UpdateItem para implementar un contador atómico. Se trata de un atributo numérico que se incrementa de forma incondicional y sin interferir con las demás solicitudes de escritura. Todas las solicitudes de escritura se aplican en el orden en que se reciben. Con un contador atómico, las actualizaciones no son idempotentes. Esto significa que el valor numérico aumenta o disminuye cada vez que se llame a UpdateItem. Si el valor de incremento que se usa para actualizar el contador atómico es positivo, se puede producir un recuento excesivo. Si el valor de incremento es negativo, se puede producir un recuento insuficiente.

Es posible utilizar un contador atómico para realizar el seguimiento del número de visitantes de un sitio web. En este caso, la aplicación incrementaría un valor numérico, independientemente del valor actual. En caso de error en la operación UpdateItem, la aplicación podría simplemente volver a intentar la operación. Aunque se correría el riesgo de actualizar dos veces el contador, seguramente sería tolerable un pequeño margen de error al alza o a la baja en el número de visitantes del sitio web.

Un contador atómico no sería adecuado en aquellos casos en que no fuese admisible un margen de error al alza o a la baja (por ejemplo, en una aplicación bancaria). En este caso, es más seguro utilizar una actualización condicional en lugar de un contador atómico.

Para obtener más información, consulte Aumento y reducción de atributos numéricos.

ejemplo

En el siguiente ejemplo de la AWS CLI se incrementa el valor de Price de un producto en 5. En este ejemplo, se sabía que el elemento existía antes de que se actualizara el contador. Dado que UpdateItem no es idempotente, el valor de Price aumentará cada vez que se ejecute el 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

Escrituras condicionales

De forma predeterminada, las operaciones de escritura de DynamoDB (PutItem, UpdateItem, DeleteItem) son incondicionales. Cada una de ellas sobrescribirá cualquier elemento existente que tenga la clave principal especificada.

Opcionalmente, DynamoDB admite las escrituras condicionales para estas operaciones. Una escritura condicional solamente se lleva a cabo si los atributos del elemento cumplen una o varias de las condiciones esperadas. En caso contrario, devuelve un error.

En las escrituras condicionales se comprueban las condiciones con la versión actualizada más reciente del elemento. Tenga en cuenta que si el elemento no existía anteriormente o si la operación más reciente que se realizó de forma correcta con ese elemento fue eliminarlo, la escritura condicional no encontrará ningún elemento anterior.

Las escrituras condicionales resultan útiles en muchas situaciones. Por ejemplo, puede ser conveniente que una operación PutItem solamente se lleve a cabo si no existe ningún elemento que tenga la misma clave principal. O puede que desee impedir que una operación UpdateItem modifique un elemento si uno de sus atributos tiene un valor determinado.

Las escrituras condicionales son útiles en aquellos casos en que varios usuarios intentan modificar el mismo elemento. Fíjese en el siguiente diagrama, en el que dos usuarios (Alice y Bob) trabajan con el mismo elemento de una tabla de DynamoDB.

Suponga que Alice utiliza la AWS CLI para actualizar el atributo Price a 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

Los argumentos de --expression-attribute-values se almacenan en el archivo expression-attribute-values.json:

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

Ahora, supongamos que Bob emite una solicitud UpdateItem parecida más adelante, pero cambia el valor de Price a 12. Para Bob, el parámetro --expression-attribute-values tendrá el siguiente aspecto:

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

Bob la solicitud de Bob se lleva a cabo, pero se pierde la actualización previa de Alice.

Para solicitar una operación PutItem, DeleteItem o UpdateItem condicional, debe especificar una expresión de condición. Una expresión de condición es una cadena que contiene nombres de atributos, operadores condicionales y funciones integradas. La totalidad de expresión debe evaluarse en true. De lo contrario, la operación no se llevará a cabo correctamente.

Ahora, fíjese en el siguiente diagrama, en el que se muestra que el uso de escrituras condicionales impediría que la actualización de Alice se sobrescribiese.

Alice intenta actualizar el valor de Price a 8, pero solamente si el valor de Price actual es 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

Los argumentos de --expression-attribute-values se almacenan en el archivo expression-attribute-values.json.

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

La actualización de Alice se lleva a cabo correctamente porque el resultado de evaluar la condición es true.

A continuación, Bob intenta actualizar el valor de Price a 12, pero solamente si el valor de Price actual es 10. Para Bob, el parámetro --expression-attribute-values tendrá el siguiente aspecto:

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

Dado que Alice ha cambiado previamente el valor de Price a 8, la expresión de condición se evalúa en false, de modo que la actualización de Bob no se lleva a cabo.

Para obtener más información, consulte Expresiones de condición.

Idempotencia de las escrituras condicionales

Las escrituras condicionales pueden ser idempotentes si la comprobación adicional está en el mismo atributo que se va a actualizar. Esto significa que DynamoDB solo realiza una determinada solicitud de escritura si determinados valores de atributo del elemento coinciden con lo que se espera que sean en el momento de la solicitud.

Por ejemplo, suponga que emite una solicitud UpdateItem para aumentar el valor de Price de un elemento en 3, pero solamente si el valor de Price actual es 20. Después de enviar la solicitud, pero antes de recibir su resultado, se produce un error en la red y usted no sabe si la solicitud se ha realizado correctamente. Como esta escritura condicional es idempotente, puede reintentar la misma solicitud UpdateItem y DynamoDB actualiza el elemento solamente si el Price de actual es 20.

Unidades de capacidad consumidas por las escrituras condicionales

Aunque el resultado de evaluar una expresión ConditionExpression sea false durante una escritura condicional, DynamoDB consume capacidad de escritura de la tabla. La cantidad consumida depende del tamaño del elemento existente (o de un mínimo de 1). Por ejemplo, si el tamaño de un elemento existente es de 300 KB y el del nuevo elemento que intenta crear o actualizar es de 310 KB, las unidades de capacidad de escritura consumidas serán 300 si falla la condición y 310 si se realiza correctamente. Si se trata de un elemento nuevo (no existente), las unidades de capacidad de escritura consumidas serán 1 si la condición falla y 310 si la condición se realiza correctamente.

nota

Las operaciones de escritura solo consumen unidades de capacidad de escritura. Nunca consumen unidades de capacidad de lectura.

Una escritura condicional que no se ha llevado a cabo devuelve la excepción ConditionalCheckFailedException. Cuando esto ocurre, no se recibe ninguna información en la respuesta sobre la capacidad de escritura que se ha consumido. Sin embargo, puede consultar la métrica ConsumedWriteCapacityUnits de la tabla en Amazon CloudWatch. Para obtener más información, consulte Métricas de DynamoDB en Registro y monitoreo en DynamoDB.

Para devolver el número de unidades de capacidad de escritura consumidas durante una escritura condicional, se usa el parámetro ReturnConsumedCapacity:

  • TOTAL: devuelve el número total de unidades de capacidad de escritura consumidas.

  • INDEXES: devuelve el número total de unidades de capacidad de escritura consumidas, con subtotales para la tabla y todos los índices secundarios que se hayan visto afectados por la operación.

  • NONE: no devuelve ningún dato de capacidad de escritura consumida. (Esta es la opción predeterminada.)

nota

A diferencia de un índice secundario global, un índice secundario local comparte su capacidad de rendimiento aprovisionada con su tabla. La actividad de lectura y escritura en un índice secundario local consume capacidad de rendimiento aprovisionada de la tabla.