

# Uso de elementos y atributos en DynamoDB
<a name="WorkingWithItems"></a>

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](HowItWorks.md).

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. 

**Topics**
+ [Tamaños y formatos de elementos de DynamoDB](CapacityUnitCalculations.md)
+ [Lectura de un elemento](#WorkingWithItems.ReadingData)
+ [Escritura de un elemento](#WorkingWithItems.WritingData)
+ [Valores devueltos](#WorkingWithItems.ReturnValues)
+ [Operaciones por lotes](#WorkingWithItems.BatchOperations)
+ [Contadores atómicos](#WorkingWithItems.AtomicCounters)
+ [Escrituras condicionales](#WorkingWithItems.ConditionalUpdate)
+ [Uso de expresiones en DynamoDB](Expressions.md)
+ [Uso del período de vida (TTL) en DynamoDB](TTL.md)
+ [Consulta de tablas en DynamoDB](Query.md)
+ [Análisis de tablas en DynamoDB](Scan.md)
+ [PartiQL: un lenguaje de consulta compatible con SQL para Amazon DynamoDB](ql-reference.md)
+ [Uso de elementos: Java](JavaDocumentAPIItemCRUD.md)
+ [Uso de elementos: .NET](LowLevelDotNetItemCRUD.md)

## Lectura de un elemento
<a name="WorkingWithItems.ReadingData"></a>

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.

**Example**  
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 [Uso de expresiones de proyección en DynamoDB](Expressions.ProjectionExpressions.md).

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

**Example**  
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
<a name="WorkingWithItems.WritingData"></a>

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
<a name="WorkingWithItems.WritingData.PutItem"></a>

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

**Example**  
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
<a name="WorkingWithItems.WritingData.UpdateItem"></a>

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 [Uso de expresiones de actualización en DynamoDB](Expressions.UpdateExpressions.md). 

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 [Uso de valores de atributos de expresión en DynamoDB](Expressions.ExpressionAttributeValues.md).

**Example**  
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 devueltos](#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
```

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
<a name="WorkingWithItems.WritingData.DeleteItem"></a>

`DeleteItem` elimina el elemento con la clave especificada.

**Example**  
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 devueltos
<a name="WorkingWithItems.ReturnValues"></a>

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
<a name="WorkingWithItems.ReturnValues.PutItem"></a>
+ `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
<a name="WorkingWithItems.ReturnValues.UpdateItem"></a>

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
<a name="WorkingWithItems.ReturnValues.DeleteItem"></a>
+ `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
<a name="WorkingWithItems.BatchOperations"></a>

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
<a name="WorkingWithItems.BatchOperations.BatchGetItem"></a>

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.

**Example**  
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
<a name="WorkingWithItems.BatchOperations.BatchWriteItem"></a>

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

**Example**  
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
<a name="WorkingWithItems.AtomicCounters"></a>

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](Expressions.UpdateExpressions.md#Expressions.UpdateExpressions.SET.IncrementAndDecrement).

**Example**  
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
<a name="WorkingWithItems.ConditionalUpdate"></a>

De forma predeterminada, las operaciones de escritura de DynamoDB (`PutItem`, `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.

![Los usuarios Alice y Bob intentan modificar un elemento con el identificador 1, lo que demuestra la necesidad de escrituras condicionales.](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/update-no-condition.png)


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.

![La escritura condicional impide que la actualización del usuario Bob sobrescriba el cambio de la usuaria Alice en el mismo elemento.](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/update-yes-condition.png)


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 [Ejemplo de la CLI de expresión de condición de DynamoDB](Expressions.ConditionExpressions.md).

### Idempotencia de las escrituras condicionales
<a name="WorkingWithItems.ConditionalWrites.Idempotence"></a>

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
<a name="WorkingWithItems.ConditionalWrites.ReturnConsumedCapacity"></a>

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.

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.