

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

# Tamaños y formatos de elementos de DynamoDB
<a name="CapacityUnitCalculations"></a>

Las tablas de DynamoDB no tienen esquemas, salvo la clave principal. Por este motivo, todos los elementos de una tabla pueden tener atributos, tamaños y tipos de datos distintos.

El tamaño total de un elemento es la suma de las longitudes de los nombres y los valores de sus atributos, además de cualquier gasto adicional aplicable, como se describe a continuación. Puede utilizar las siguientes directrices para calcular el tamaño de los atributos:
+ Los valores de tipo String son Unicode con codificación binaria UTF-8. El tamaño de una cadena es *(número de bytes con codificación UTF-8 del nombre de atributo) \$1 (número de bytes con codificación UTF-8)*.
+ Los números son de longitud variable, con un máximo de 38 dígitos significativos. Los ceros iniciales y finales se recortan. El tamaño aproximado de un número es *(número de bytes con codificación UTF-8 del nombre de atributo) \$1 (1 byte por cada dos dígitos significativos) \$1 (1 byte)*.
+ Un valor binario se debe codificar previamente en formato base64 para poder enviarlo a DynamoDB. Sin embargo, para calcular su tamaño se utiliza la longitud en bytes sin procesar del valor. El tamaño de un atributo binario es *(número de bytes con codificación UTF-8 del nombre de atributo) \$1 (número de bytes sin procesar)*.
+ El tamaño de un atributo nulo o booleano es *(número de bytes con codificación UTF-8 del nombre de atributo) \$1 (1 byte)*.
+ Un atributo de tipo `List` o `Map` requiere 3 bytes adicionales, independientemente de su contenido. El tamaño de un atributo `List` o `Map` es *(número de bytes con codificación UTF-8 del nombre de atributo) \$1 suma (tamaño de los elementos anidados) \$1 (3 bytes)*. El tamaño de un atributo `List` o `Map` vacío es *(número de bytes con codificación UTF-8 del nombre de atributo) \$1 (3 bytes)*.
+ Cada elemento `List` o `Map` también requiere 1 byte de sobrecarga.

**nota**  
Recomendamos elegir nombres de atributos cortos en lugar de largos. Esto le ayuda a reducir la cantidad de almacenamiento necesario, así como la cantidad de RCU/WCU que utiliza.

A efectos de facturación del almacenamiento, cada elemento incluye una capacidad de almacenamiento adicional por elemento que depende de las características que haya habilitado.
+ Todos los elementos de DynamoDB requieren 100 bytes de capacidad de almacenamiento adicional para la indexación.
+ Algunas características de DynamoDB (tablas globales, transacciones, captura de datos de cambios para Kinesis Data Streams con DynamoDB) requieren una capacidad de almacenamiento adicional para tener en cuenta los atributos creados por el sistema como resultado de la habilitación de dichas características. Por ejemplo, las tablas globales requieren 48 bytes adicionales de capacidad de almacenamiento.

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

# Uso de expresiones en DynamoDB
<a name="Expressions"></a>

En Amazon DynamoDB, puede usar *expresiones* para especificar qué atributos leer de un elemento, escribir datos cuando se cumple una condición, especificar cómo actualizar un elemento, definir consultas y filtrar los resultados de una consulta.

En esta tabla se describen los aspectos gramaticales básicos de las expresiones y los tipos de expresiones disponibles.


| Tipo de expresión | Descripción | 
| --- | --- | 
| Expresión de proyección | Una expresión de proyección identifica los atributos que se desean recuperar de un elemento cuando se utilizan operaciones como GetItem, Query o Scan. | 
| Expresión de condición | Una expresión de condición determina qué elementos deben modificarse al utilizar las operaciones PutItem, UpdateItem y DeleteItem. | 
| Expresión de actualización | Una expresión de actualización especifica cómo UpdateItem modificará los atributos de un elemento; por ejemplo, estableciendo un valor escalar o eliminando elementos de una lista o un mapa. | 
| Expresión de condición de clave | Una expresión de condición clave determina qué elementos leerá una consulta de una tabla o índice. | 
| Expresión de filtro | Una expresión de filtro determina qué elementos entre los resultados de consulta se deben devolver al usuario. Todos los demás resultados se descartan. | 

Para obtener información sobre la sintaxis de expresión e información más detallada sobre cada tipo de expresión, consulte las secciones siguientes.

**Topics**
+ [Referencia a atributos de elementos mediante expresiones en DynamoDB](Expressions.Attributes.md)
+ [Nombres de atributos de expresión (Alias) en DynamoDB](Expressions.ExpressionAttributeNames.md)
+ [Uso de valores de atributos de expresión en DynamoDB](Expressions.ExpressionAttributeValues.md)
+ [Uso de expresiones de proyección en DynamoDB](Expressions.ProjectionExpressions.md)
+ [Uso de expresiones de actualización en DynamoDB](Expressions.UpdateExpressions.md)
+ [Expresiones, operadores y funciones de condición y filtro en DynamoDB](Expressions.OperatorsAndFunctions.md)
+ [Ejemplo de la CLI de expresión de condición de DynamoDB](Expressions.ConditionExpressions.md)

**nota**  
Con el fin de ofrecer compatibilidad retroactiva, DynamoDB también admite parámetros condicionales que no utilizan expresiones. Para obtener más información, consulte [Parámetros condicionales de DynamoDB heredados](LegacyConditionalParameters.md).  
Las nuevas aplicaciones deben utilizar expresiones en lugar de los parámetros heredados.

# Referencia a atributos de elementos mediante expresiones en DynamoDB
<a name="Expressions.Attributes"></a>

En esta sección se describe cómo consultar los atributos de los elementos en una expresión en Amazon DynamoDB. Puede utilizar cualquier atributo, aunque se encuentre anidado profundamente en varias listas y mapas.

**Topics**
+ [Atributos de nivel superior](#Expressions.Attributes.TopLevelAttributes)
+ [Atributos anidados](#Expressions.Attributes.NestedAttributes)
+ [Rutas de documento](#Expressions.Attributes.NestedElements.DocumentPathExamples)

**Ejemplo de elemento: ProductCatalog**  
Los ejemplos de esta página utilizan el siguiente elemento de muestra de la tabla de `ProductCatalog`. Esta tabla se describe en . [Tablas y datos de ejemplo para usar en 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"
 }
```

Tenga en cuenta lo siguiente:
+ El valor de la clave de partición (`Id`) es `123`. No hay clave de ordenación.
+ Los tipos de datos de la mayoría de los atributos son escalares, tales como `String`, `Number`, `Boolean` y `Null`.
+ Un atributo (`Color`) es de tipo `String Set`.
+ Los siguientes atributos tienen tipos de datos de documento:
  + Una lista de `RelatedItems`. Cada componente es un `Id` de un producto relacionado.
  + Mapa de imágenes () `Pictures`. Cada componente es una descripción breve de una imagen, junto con una dirección URL del archivo de imagen correspondiente.
  + Mapa de imágenes () `ProductReviews`. Cada componente representa una clasificación y una lista de opiniones correspondientes a esa clasificación. Inicialmente, este mapa se rellena con opiniones de cinco estrellas y una estrella.

## Atributos de nivel superior
<a name="Expressions.Attributes.TopLevelAttributes"></a>

Se considera que un atributo es de *nivel superior* si no está integrado en otro atributo. En el elemento `ProductCatalog`, los atributos de nivel superior son:
+ `Id`
+ `Title`
+ `Description`
+ `BicycleType`
+ `Brand`
+ `Price`
+ `Color`
+ `ProductCategory`
+ `InStock`
+ `QuantityOnHand`
+ `RelatedItems`
+ `Pictures`
+ `ProductReviews`
+ `Comment`
+ `Safety.Warning`

Todos estos atributos de nivel superior son escalares, con la salvedad de `Color` (lista), `RelatedItems` (lista), `Pictures` (mapa) y `ProductReviews` (mapa).

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

Se considera que un atributo es *anidado* si está integrado en otro atributo. Para obtener acceso a un atributo anidado, se utilizan los *operadores de desreferenciación*:
+ `[n]`: para elementos de lista
+ `.` (punto): para elementos de mapa

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

El operador de desreferencia de un elemento de la lista es **[*N*]**, donde *n* es el número del elemento. Las entradas de lista están basadas en cero; es decir, [0] representa la primera entrada de la lista, [1] representa la segunda, y así sucesivamente. Estos son algunos ejemplos:
+ `MyList[0]`
+ `AnotherList[12]`
+ `ThisList[5][11]`

La entrada `ThisList[5]` es una lista anidada en sí misma. Por consiguiente, `ThisList[5][11]` se refiere al duodécimo componente de esa lista.

El número contenido entre corchetes debe ser un entero no negativo. Por lo tanto, las siguientes expresiones no son válidas:
+ `MyList[-1]`
+ `MyList[0.4]`

### Acceso a los elementos de un mapa
<a name="Expressions.Attributes.NestedElements.AccessingMapElements"></a>

El operador de desreferenciación de una entrada de un mapa es **. ** (un punto). Utilice el punto como separador entre las entradas de un mapa:
+ `MyMap.nestedField`
+ `MyMap.nestedField.deeplyNestedField`

## Rutas de documento
<a name="Expressions.Attributes.NestedElements.DocumentPathExamples"></a>

En una expresión, se utiliza una *ruta de documento* para indicar a DynamoDB dónde se encuentra un atributo. En el caso de un atributo de nivel superior, la ruta de documento es el nombre de atributo. En el caso de un atributo anidado, se utilizan operadores de desreferenciación para construir la ruta de documento.

A continuación se indican algunos ejemplos de rutas de documentos. Consulte el elemento mostrado en . [Referencia a atributos de elementos mediante expresiones en DynamoDB](#Expressions.Attributes).)
+ Atributo escalar de nivel superior.

   `Description`
+ Atributo de lista de nivel superior. (Devuelve la lista completa, no solo algunos de los componentes).

  `RelatedItems`
+ Tercera entrada de la lista `RelatedItems`. Recuerde que las entradas de lista se basan en cero.

  `RelatedItems[2]`
+ Imagen frontal del producto.

  `Pictures.FrontView`
+ Todas las opiniones de cinco estrellas.

  `ProductReviews.FiveStar`
+ Primera de las opiniones de cinco estrellas.

  `ProductReviews.FiveStar[0]`

**nota**  
La profundidad máxima de una ruta de documento es 32. Por lo tanto, el número de operadores de desreferenciación de una ruta no puede superar este límite.

Puede utilizar cualquier nombre de atributo en la ruta de un documento siempre que cumpla estos requisitos:
+ El primer carácter es `a-z`, `A-Z` o `0-9`
+ El segundo carácter (si está presente) es `a-z` o `A-Z`

**nota**  
Si un nombre de atributo no cumple este requisito, tendrá que definir un nombre de atributo de expresión como marcador de posición.

Para obtener más información, consulte [Nombres de atributos de expresión (Alias) en DynamoDB](Expressions.ExpressionAttributeNames.md).

# Nombres de atributos de expresión (Alias) en DynamoDB
<a name="Expressions.ExpressionAttributeNames"></a>

Un *nombre de atributo de expresión* es un alias (o marcador de posición) que se utiliza en una expresión de Amazon DynamoDB en lugar del nombre de atributo real. Un nombre de atributo de expresión debe comenzar por un signo de almohadilla (`#`) y debe ir seguido de uno o más caracteres alfanuméricos. También se permite el carácter de subrayado (`_`).

En esta sección se describen varias situaciones en las que debe utilizar nombres de atributos de expresión.

**nota**  
En los ejemplos de esta sección se utiliza la AWS Command Line Interface (AWS CLI). 

**Topics**
+ [Palabras reservadas](#Expressions.ExpressionAttributeNames.ReservedWords)
+ [Nombres de atributo que contienen caracteres especiales](#Expressions.ExpressionAttributeNames.AttributeNamesContainingSpecialCharacters)
+ [Atributos anidados](#Expressions.ExpressionAttributeNames.NestedAttributes)
+ [Hacer referencia repetidamente a nombres de atributos](#Expressions.ExpressionAttributeNames.RepeatingAttributeNames)

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

En algunas ocasiones, es posible que necesite escribir una expresión que contenga un nombre de atributo que entre en conflicto con una palabra reservada de DynamoDB. Para obtener una lista completa de palabras reservadas, consulte . [Palabras reservadas en DynamoDB](ReservedWords.md).)

Por ejemplo, el siguiente ejemplo de la AWS CLI no funcionaría correctamente porque `COMMENT` es una palabra reservada,

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

Para solucionar este problema, puede sustituir `Comment` por un nombre de atributo de expresión; por ejemplo, `#c`. El símbolo de almohadilla (`#`) es obligatorio e indica que se trata de un marcador de posición del nombre de un atributo. Ahora, el ejemplo de la AWS CLI tendría el siguiente aspecto.

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

**nota**  
Si un nombre de atributo comienza por un número, contiene un espacio o contiene una palabra reservada, *debe* utilizar un nombre de atributo de expresión para reemplazar el nombre de ese atributo en la expresión.

## Nombres de atributo que contienen caracteres especiales
<a name="Expressions.ExpressionAttributeNames.AttributeNamesContainingSpecialCharacters"></a>

En una expresión, un punto (".") se interpreta como un carácter separador en una ruta de documento. No obstante, DynamoDB también le permite utilizar un carácter de punto y otros caracteres especiales, como un guion ("-") como parte de un nombre de atributo. En algunos casos, esto puede dar lugar a ambigüedades. A modo de ejemplo, supongamos que desea recuperar el atributo `Safety.Warning` de un elemento `ProductCatalog` (consulte [Referencia a atributos de elementos mediante expresiones en DynamoDB](Expressions.Attributes.md)).

Supongamos que desea obtener acceso a `Safety.Warning` mediante una expresión de proyección.

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

DynamoDB podría devolver un resultado vacío, en lugar de la cadena prevista ("`Always wear a helmet`"). El motivo es que DynamoDB interpreta el punto en una expresión como un separador de ruta de documento. En este caso, tiene que definir un nombre de atributo de expresión (por ejemplo, `#sw`) como sustituto de `Safety.Warning`. A continuación, podría utilizar la siguiente expresión de proyección.

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

Ahora, DynamoDB devolvería el resultado correcto.

**nota**  
Si un nombre de atributo contiene un punto (".") o un guion ("-"), *debe* utilizar un nombre de atributo de expresión para reemplazar el nombre de ese atributo en la expresión.

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

Suponga que desea acceder al atributo anidado `ProductReviews.OneStar`. En el nombre de un atributo de expresión, DynamoDB trata el punto (".") como un carácter del nombre del atributo. Para hacer referencia al atributo anidado, defina un nombre de atributo de expresión para cada elemento de la ruta del documento:
+ `#pr — ProductReviews`
+ `#1star — OneStar`

A continuación, habría que usar `#pr.#1star` para la expresión de proyección.

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

Ahora, DynamoDB devolvería el resultado correcto.

## Hacer referencia repetidamente a nombres de atributos
<a name="Expressions.ExpressionAttributeNames.RepeatingAttributeNames"></a>

Expresión los nombres de atributos de expresión resultan útiles cuando es preciso consultar repetidamente el mismo nombre de atributo. Por ejemplo, tomemos la siguiente expresión para recuperar algunas de las opiniones de un elemento de `ProductCatalog`.

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

Para que resulte más concisa, puede sustituir `ProductReviews` por un nombre de atributo de expresión, como `#pr`. Ahora, la expresión revisada tendría el siguiente aspecto.
+  `#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"}'
```

Si define un nombre de atributo de expresión, debe usarlo de forma coherente en toda la expresión. Además, es importante no omitir el signo `#`. 

# Uso de valores de atributos de expresión en DynamoDB
<a name="Expressions.ExpressionAttributeValues"></a>

*Los valores de los atributos de expresión* de Amazon DynamoDB actúan como variables. Reemplazan a los valores reales que se desea comparar, que podrían no conocerse hasta el tiempo de ejecución. Un valor de atributo de expresión debe comenzar por un signo de dos puntos (`:`) y debe ir seguido de uno o más caracteres alfanuméricos.

Por ejemplo, supongamos que desea devolver todos los elementos de `ProductCatalog`que estén disponibles en el color `Black` y tengan un precio de `500` o menos. Podría utilizar una operación `Scan` con una expresión de filtro, como en este ejemplo de la 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
```

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

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

Si define un valor de atributo de expresión, debe usarlo de forma coherente en toda la expresión. Además, es importante no omitir el signo `:`. 

Los valores de atributos de expresión se usan con expresiones de condición de clave, expresiones de condición, expresiones de actualización y expresiones de filtro.

# Uso de expresiones de proyección en DynamoDB
<a name="Expressions.ProjectionExpressions"></a>

Para leer datos de una tabla, se utilizan operaciones tales como `GetItem`, `Query` o `Scan`. De forma predeterminada, Amazon DynamoDB devuelve todos los atributos de los elementos. Si desea obtener solo uno en lugar de todos ellos, debe usar una expresión de proyección.

Una *expresión de proyección* es una cadena que identifica los atributos que se desea. Para recuperar un solo atributo, especifique su nombre. Si desea obtener varios atributos, separe sus nombres mediante comas.

A continuación se muestran ejemplos de expresiones de proyección basadas en el elemento `ProductCatalog` de [Referencia a atributos de elementos mediante expresiones en DynamoDB](Expressions.Attributes.md):
+ Un solo atributo de nivel superior.

  `Title `
+ Tres atributos de nivel superior. DynamoDB recupera todo el conjunto `Color`.

  `Title, Price, Color`
+ Cuatro atributos de nivel superior. DynamoDB devolverá todo el contenido de `RelatedItems` y `ProductReviews`.

  `Title, Description, RelatedItems, ProductReviews`

**nota**  
La expresión de proyección no modifica el consumo de rendimiento aprovisionado. DynamoDB determina las unidades de capacidad consumidas según el tamaño de los elementos y no según la cantidad de datos que se devuelven a una aplicación.

**Palabras reservadas y caracteres especiales**

DynamoDB tiene palabras reservadas y caracteres especiales. DynamoDB le permite utilizar estas palabras reservadas y caracteres especiales para nombres, pero le recomendamos que evite hacerlo, porque tendría que usar alias para ellos cada vez que utilizase estos nombres en una expresión. Para ver una lista completa, consulte [Palabras reservadas en DynamoDB](ReservedWords.md).

Deberá usar los nombres de los atributos de la expresión en lugar del nombre real si: 
+ El nombre del atributo está en la lista de palabras reservadas en DynamoDB.
+ El nombre del atributo no cumple el requisito de que el primer carácter sea `a-z` o `A-Z` y que el segundo carácter (si lo hay) sea `a-Z`, `A-Z` o `0-9`.
+ El nombre del atributo contiene un signo **\$1** (hash) o **:** (dos puntos).

En el ejemplo de la AWS CLI siguiente se muestra cómo usar una expresión de proyección con una operación `GetItem`. La expresión de proyección recupera un atributo escalar de nivel superior (`Description`), la primera entrada de una lista (`RelatedItems[0]`) y una lista anidada en un mapa (`ProductReviews.FiveStar`).

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

Para este ejemplo, se devolvería el siguiente código JSON.

```
{
    "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"
                }
            ]
        }
    }
}
```

# Uso de expresiones de actualización en DynamoDB
<a name="Expressions.UpdateExpressions"></a>

La acción `UpdateItem` actualiza un elemento existente o agrega uno nuevo a la tabla, si no existe ya. Es preciso proporcionar la clave del elemento que se desea actualizar. Asimismo, debe proporcionar una expresión de actualización que indique los atributos que se van a modificar y los valores que se les asignarán. 

Una *expresión de actualización* especifica cómo `UpdateItem` modificará los atributos de un elemento; por ejemplo, estableciendo un valor escalar o eliminando elementos de una lista o un mapa.

A continuación se muestra un resumen de la sintaxis de las expresiones de actualización.

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

Una expresión de actualización consta de una o varias cláusulas. Cada cláusula comienza con una palabra clave `SET`, `REMOVE`, `ADD` o `DELETE`. Puede incluir cualquiera de estas cláusulas en una expresión de actualización, en cualquier orden. Sin embargo, cada palabra clave de acción solo puede aparecer una vez.

Cada cláusula contiene una o más acciones, separadas por comas. Cada acción representa una modificación de datos.

Los ejemplos que aparecen en esta sección se basan en el elemento `ProductCatalog` que se muestra en [Uso de expresiones de proyección en DynamoDB](Expressions.ProjectionExpressions.md).

En los temas siguientes se describen algunos casos de uso diferentes de la acción `SET`.

**Topics**
+ [SET: modificación o adición de atributos de elemento](#Expressions.UpdateExpressions.SET)
+ [REMOVE: eliminación de atributos de un elemento](#Expressions.UpdateExpressions.REMOVE)
+ [ADD: actualización de números y conjuntos](#Expressions.UpdateExpressions.ADD)
+ [DELETE: eliminación de elementos de un conjunto](#Expressions.UpdateExpressions.DELETE)
+ [Uso de varias expresiones de actualización](#Expressions.UpdateExpressions.Multiple)

## SET: modificación o adición de atributos de elemento
<a name="Expressions.UpdateExpressions.SET"></a>

Utilice la acción `SET` en una expresión de actualización para agregar uno o varios atributos a un elemento. Si cualquiera de estos atributos ya existe, se sobrescribirá con los nuevos valores. Si desea evitar sobrescribir un atributo existente, puede utilizar `SET` con la función `if_not_exists`. La función `if_not_exists` es específica de la acción `SET` y solamente se puede utilizar en una expresión de actualización.

Cuando se utiliza `SET` para actualizar una entrada de lista, el contenido de esa entrada se sustituye por los nuevos datos que ha especificado. Si el componente no existe, `SET` adjunta el nuevo componente al final de la lista.

Si agrega varias entradas en una misma operación `SET`, las entradas se ordenan según su número.

También puede utilizar `SET` para sumar o restar un valor de un atributo de tipo `Number`. Para llevar a cabo varias acciones `SET`, debe separarlas por comas.

En el resumen de sintaxis siguiente:
+ El componente *path* es la ruta de documento del elemento.
+ Un componente **operand** puede ser una ruta de documento a un elemento o una función.

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

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

operand ::=
    path | function

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

Si el elemento no contiene un atributo en la ruta especificada, `if_not_exists` se evalúa en `value`. De lo contrario, se evalúa como `path`.

La siguiente operación `PutItem` crea un elemento de muestra al que se refieren los ejemplos.

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

Los argumentos de `--item` se almacenan en el archivo `item.json`. Para simplificar, se utilizan tan solo algunos de los atributos de elementos.

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

**Topics**
+ [Modificación de atributos](#Expressions.UpdateExpressions.SET.ModifyingAttributes)
+ [Adición de listas y mapas](#Expressions.UpdateExpressions.SET.AddingListsAndMaps)
+ [Adición de elementos a una lista](#Expressions.UpdateExpressions.SET.AddingListElements)
+ [Adición de atributos de mapa anidados](#Expressions.UpdateExpressions.SET.AddingNestedMapAttributes)
+ [Aumento y reducción de atributos numéricos](#Expressions.UpdateExpressions.SET.IncrementAndDecrement)
+ [Adición de elementos a una lista](#Expressions.UpdateExpressions.SET.UpdatingListElements)
+ [Cómo evitar sobrescribir un atributo existente](#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites)

### Modificación de atributos
<a name="Expressions.UpdateExpressions.SET.ModifyingAttributes"></a>

**Example**  
Actualice los atributos `ProductCategory` y `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
```
Los argumentos de `--expression-attribute-values` se almacenan en el archivo `values.json`.  

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

**nota**  
En la operación `UpdateItem`, `--return-values ALL_NEW` hace que DynamoDB devuelva el elemento tal y como aparece después de la actualización.

### Adición de listas y mapas
<a name="Expressions.UpdateExpressions.SET.AddingListsAndMaps"></a>

**Example**  
Agregue una lista y un mapa nuevos.  

```
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
```
Los argumentos de `--expression-attribute-values` se almacenan en el archivo `values.json`.  

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

### Adición de elementos a una lista
<a name="Expressions.UpdateExpressions.SET.AddingListElements"></a>

**Example**  
Agregue un nuevo atributo a la lista `RelatedItems`. Recuerde que las entradas de lista están basadas en cero; es decir, [0] representa la primera entrada de la lista, [1] representa la segunda, y así sucesivamente.  

```
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
```
Los argumentos de `--expression-attribute-values` se almacenan en el archivo `values.json`.  

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

**nota**  
Cuando se utiliza `SET` para actualizar una entrada de lista, el contenido de esa entrada se sustituye por los nuevos datos que ha especificado. Si el componente no existe, `SET` adjunta el nuevo componente al final de la lista.  
Si agrega varias entradas en una misma operación `SET`, las entradas se ordenan según su número.

### Adición de atributos de mapa anidados
<a name="Expressions.UpdateExpressions.SET.AddingNestedMapAttributes"></a>

**Example**  
Agregue algunos atributos de mapa anidados.  

```
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
```
Los argumentos de `--expression-attribute-names` se almacenan en el archivo `names.json`.  

```
{
    "#pr": "ProductReviews",
    "#5star": "FiveStar",
    "#3star": "ThreeStar"
}
```
Los argumentos de `--expression-attribute-values` se almacenan en el archivo `values.json`.  

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

**importante**  
No puede actualizar los atributos de mapa anidados si el mapa principal no existe. Si intenta actualizar un atributo anidado (por ejemplo, `ProductReviews.FiveStar`) cuando el mapa principal (`ProductReviews`) no existe, DynamoDB devuelve un elemento `ValidationException` con el mensaje *«The document path provided in the update expression is invalid for update»*.  
Al crear elementos cuyos atributos de mapa anidados se vayan a actualizar más adelante, inicialice los mapas vacíos para los atributos principales. Por ejemplo:  

```
{
    "Id": {"N": "789"},
    "ProductReviews": {"M": {}},
    "Metadata": {"M": {}}
}
```
Esto le permite actualizar los atributos anidados como `ProductReviews.FiveStar` sin errores.

### Aumento y reducción de atributos numéricos
<a name="Expressions.UpdateExpressions.SET.IncrementAndDecrement"></a>

Puede sumar o restar un valor a un atributo numérico. Para ello, se utilizan los operadores `+` (más) y `-` (menos).

**Example**  
Reduzca el `Price` de un elemento.  

```
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 el valor de `Price`, se utiliza el operador `+` en la expresión de actualización.

### Adición de elementos a una lista
<a name="Expressions.UpdateExpressions.SET.UpdatingListElements"></a>

Puede agregar componentes al final de una lista. Para ello, se utiliza `SET` con la función `list_append`. (El nombre de la función distingue entre mayúsculas y minúsculas). La función `list_append` es específica de la acción `SET` y solamente se puede utilizar en una expresión de actualización. La sintaxis es la siguiente.
+ `list_append (list1, list2)`

La función toma dos listas como entrada y anexa todos los elementos de `list2` a ` list1`.

**Example**  
En [Adición de elementos a una lista](#Expressions.UpdateExpressions.SET.AddingListElements), ha creado la lista `RelatedItems` y ha incluido en ella dos componentes: `Hammer` y `Nails`. Ahora, va a agregar dos componentes más al 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
```
Los argumentos de `--expression-attribute-values` se almacenan en el archivo `values.json`.  

```
{
    ":vals": {
        "L": [
            { "S": "Screwdriver" },
            {"S": "Hacksaw" }
        ]
    }
}
```
Por último, vamos a agregar un componente más al *principio* de `RelatedItems`. Para ello, invierta el orden de los componentes de `list_append`. (Recuerde que `list_append` toma dos listas como información de entrada y agrega la segunda lista a la primera).  

```
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
```
Ahora, el atributo `RelatedItems` resultante contiene cinco entradas, el siguiente orden: `Chisel`, `Hammer`, `Nails`, `Screwdriver` y `Hacksaw`.

### Cómo evitar sobrescribir un atributo existente
<a name="Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites"></a>

**Example**  
Establezca el valor de `Price` de un elemento, pero solo si este no tiene ya un atributo `Price`. (Si `Price` ya existe, no sucede 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: eliminación de atributos de un elemento
<a name="Expressions.UpdateExpressions.REMOVE"></a>

Utilice la acción `REMOVE` en una expresión de actualización para eliminar uno o varios atributos de un elemento en Amazon DynamoDB. Para llevar a cabo varias acciones `REMOVE`, debe separarlas por comas.

A continuación se muestra un resumen de la sintaxis de `REMOVE` en una expresión de actualización. El único operando es la ruta de documento del atributo que se desea eliminar.

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

**Example**  
Elimine algunos atributos de un elemento. (Si el atributo no existe, no sucede nada).  

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

### Eliminación de elementos de una lista
<a name="Expressions.UpdateExpressions.REMOVE.RemovingListElements"></a>

Puede utilizar `REMOVE` para eliminar entradas individuales de una lista.

**Example**  
En [Adición de elementos a una lista](#Expressions.UpdateExpressions.SET.UpdatingListElements), ha modificado un atributo de lista (`RelatedItems`) para que contenga cinco componentes:   
+ `[0]`—`Chisel`
+ `[1]`—`Hammer`
+ `[2]`—`Nails`
+ `[3]`—`Screwdriver`
+ `[4]`—`Hacksaw`
En el siguiente ejemplo de la AWS Command Line Interface (AWS CLI) se eliminan `Hammer` y `Nails` de la lista.  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE RelatedItems[1], RelatedItems[2]" \
    --return-values ALL_NEW
```
Después de eliminar `Hammer` y `Nails`, los componentes restantes se reordenan. Ahora, la lista contiene lo siguiente:  
+ `[0]`—`Chisel`
+ `[1]`—`Screwdriver`
+ `[2]`—`Hacksaw`

## ADD: actualización de números y conjuntos
<a name="Expressions.UpdateExpressions.ADD"></a>

**nota**  
En general, recomendamos usar `SET` en lugar de `ADD` para garantizar operaciones idempotentes.

Utilice la acción `ADD` en una expresión de actualización para agregar un nuevo atributo y sus valores a un elemento.

Si el atributo ya existe, el comportamiento de `ADD` depende del tipo de datos del atributo:
+ Si el atributo es un número y el valor que se agrega también es un número, entonces el valor se suma matemáticamente al atributo existente. (Si el valor es un número negativo, entonces se resta del atributo existente).
+ Si el atributo es un conjunto y el valor que se agrega también es un conjunto, entonces el valor se agrega al conjunto existente.

**nota**  
La acción `ADD` solo es compatible con los tipos de datos Number y Set.

Para llevar a cabo varias acciones `ADD`, debe separarlas por comas.

En el resumen de sintaxis siguiente:
+ El componente *path* es la ruta de documento de un atributo. El tipo de datos del atributo debe ser `Number` o Set. 
+ El componente *value* es un número que se desea agregar al atributo (si el tipo de datos es `Number`) o un conjunto que se desea agregar al atributo (si el tipo de datos es Set).

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

En los temas siguientes se describen algunos casos de uso diferentes de la acción `ADD`.

**Topics**
+ [Adición de un número](#Expressions.UpdateExpressions.ADD.Number)
+ [Adición de elementos a un conjunto](#Expressions.UpdateExpressions.ADD.Set)

### Adición de un número
<a name="Expressions.UpdateExpressions.ADD.Number"></a>

Supongamos que el atributo `QuantityOnHand` no existe. En el siguiente ejemplo de la AWS CLI, `QuantityOnHand` se establece en 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
```

Ahora que `QuantityOnHand` ya existe, puede volver a ejecutar el ejemplo para incrementar `QuantityOnHand` en 5 cada vez.

### Adición de elementos a un conjunto
<a name="Expressions.UpdateExpressions.ADD.Set"></a>

Supongamos que el atributo `Color` no existe. En el siguiente ejemplo de la AWS CLI, `Color` se establece en un conjunto de cadenas que contiene dos componentes.

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

Ahora que `Color` ya existe, podemos agregarle más componentes.

```
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: eliminación de elementos de un conjunto
<a name="Expressions.UpdateExpressions.DELETE"></a>

**importante**  
La acción `DELETE` solo es compatible con tipos de datos `Set`.

Utilice la acción `DELETE` en una expresión de actualización para eliminar una o varias entradas de un conjunto. Para llevar a cabo varias acciones `DELETE`, debe separarlas por comas.

En el resumen de sintaxis siguiente:
+ El componente *path* es la ruta de documento de un atributo. El tipo de datos del atributo debe ser Set.
+ *Subset* representa uno o varios componentes que se van a eliminar de *path*. Para *subset* debe especificar un tipo de datos Set.

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

**Example**  
En [Adición de elementos a un conjunto](#Expressions.UpdateExpressions.ADD.Set), crea el conjunto de cadenas `Color`. En este ejemplo se eliminan algunos de los componentes de ese 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
```

## Uso de varias expresiones de actualización
<a name="Expressions.UpdateExpressions.Multiple"></a>

Puede utilizar varias acciones en una sola expresión de actualización. Todas las referencias de atributos se resuelven en función del estado del elemento antes de aplicar cualquiera de las acciones.

**Example**  
Dado un elemento `{"id": "1", "a": 1, "b": 2, "c": 3}`, la siguiente expresión elimina `a` y desplaza los valores de `b` y `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
```
El resultado es `{"id": "1", "b": 1, "c": 2}`. Aunque `a` se elimina y `b` se reasigna en la misma expresión, ambas referencias se resuelven con sus valores originales.

**Example**  
Si desea modificar el valor de un atributo y eliminar por completo otro, podría utilizar una acción SET y otra REMOVE en una sola instrucción. Esta operación reduciría el valor de `Price` a 15 a la vez que eliminaría el atributo `InStock` del elemento.  

```
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**  
Si desea agregar un elemento a una lista al mismo tiempo que cambia el valor de otro atributo, podría utilizar dos acciones SET en una sola instrucción. Esta operación agregaría "Nails" al atributo de la lista `RelatedItems` y también establecería el valor de `Price` a 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
```

# Expresiones, operadores y funciones de condición y filtro en DynamoDB
<a name="Expressions.OperatorsAndFunctions"></a>

Para manipular datos en una tabla de DynamoDB, se usan las operaciones `PutItem`, `UpdateItem` y `DeleteItem`. Para estas operaciones de manipulación de datos, puede especificar una expresión de condición con el fin de determinar qué elementos deben modificarse. Si la expresión de condición se evalúa en true, entonces la operación se realiza correctamente. De lo contrario, la operación no se llevará a cabo correctamente.

En esta sección se describen las funciones y las palabras clave integradas para escribir expresiones de filtro y condición en Amazon DynamoDB. Para obtener más información sobre las funciones y la programación con DynamoDB, consulte [Programación con DynamoDB y los SDK de AWS](Programming.md) y la [Referencia de la API de DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/).

**Topics**
+ [Sintaxis de las expresiones de filtro y condición](#Expressions.OperatorsAndFunctions.Syntax)
+ [Realización de comparaciones](#Expressions.OperatorsAndFunctions.Comparators)
+ [Funciones](#Expressions.OperatorsAndFunctions.Functions)
+ [Evaluaciones lógicas](#Expressions.OperatorsAndFunctions.LogicalEvaluations)
+ [Paréntesis](#Expressions.OperatorsAndFunctions.Parentheses)
+ [Precedencia en las condiciones](#Expressions.OperatorsAndFunctions.Precedence)

## Sintaxis de las expresiones de filtro y condición
<a name="Expressions.OperatorsAndFunctions.Syntax"></a>

En el siguiente resumen de sintaxis, el componente *operand* puede ser uno de los siguientes: 
+ Un nombre de atributo de nivel superior, como por ejemplo `Id`, `Title`, `Description` o `ProductCategory`
+ Una ruta de documento que hace referencia a un atributo anidado

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

## Realización de comparaciones
<a name="Expressions.OperatorsAndFunctions.Comparators"></a>

Utilice estos comparadores para comparar un operando con un solo valor:
+ `a = b`: es true si *a* es igual que *b*.
+ `a <> b`: es true si *a* es distinto de *b*.
+ `a < b`: es true si *a* es menor que *b*.
+ `a <= b`: es true si *a* es menor o igual que *b*.
+ `a > b`: es true si *a* es mayor que *b*.
+ `a >= b`: es true si *a* es mayor o igual que *b*.

Use las palabras clave `BETWEEN` e `IN` para comparar un operando con un rango o una lista de valores:
+ `a BETWEEN b AND c`: es true si *a* es mayor o igual que *b* y menor o igual que *c*.
+ `a IN (b, c, d) `: es true si *a* es igual a cualquiera de los valores de la lista; por ejemplo, en este caso, a *b*, *c* o *d*. La lista puede contener hasta 100 valores separadas por comas.

## Funciones
<a name="Expressions.OperatorsAndFunctions.Functions"></a>

Utilice las siguientes funciones para determinar si un atributo existe en un elemento o evaluar el valor de un atributo. Los nombres de estas funciones distinguen entre mayúsculas y minúsculas. En el caso de los atributos anidados, debe proporcionar su ruta de documento completa.


****  

| Función | Descripción | 
| --- | --- | 
|  `attribute_exists (path)`  | Es true si el elemento contiene el atributo especificado por `path`. Ejemplo: Comprobación de si un elemento de la tabla `Product` tiene una imagen de vista lateral. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 
|  `attribute_not_exists (path)`  | Es true si el atributo especificado en `path` no está presente en el elemento. Ejemplo: Comprobación de si un elemento tiene el atributo `Manufacturer`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 
|  `attribute_type (path, type)`  |  Es true si el atributo de la ruta especificada es de un tipo de datos determinado. El parámetro `type` debe ser uno de los siguientes: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Debe utilizar un valor de atributo de expresión para el parámetro `type`. Ejemplo: Comprobación de si el atributo `QuantityOnHand` es del tipo List. En este ejemplo, `:v_sub` es un marcador de posición para la `L`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Debe utilizar un valor de atributo de expresión para el parámetro `type`.   | 
|  `begins_with (path, substr)`  |  Es true si el atributo especificado por `path` comienza por una subcadena determinada. Ejemplo: Comprobación de si los primeros caracteres de la URL de la imagen de vista frontal son `http://`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) El valor de atributo de expresión `:v_sub` es un marcador de posición para `http://`.  | 
|  `contains (path, operand)`  | Es true si el atributo especificado por `path` es uno de los siguientes: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) Si el atributo especificado por `path` es un `String`, el `operand` debe ser un `String`. Si el atributo especificado por `path` es un `Set`, el `operand` debe ser el tipo de elemento del conjunto. La ruta y el operando deben ser distintos. Es decir, `contains (a, a)` devuelve un error. Ejemplo: Comprobación de si el atributo `Brand` contiene la subcadena `Company`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) El valor de atributo de expresión `:v_sub` es un marcador de posición para `Company`. Ejemplo: Comprobación de si el producto está disponible en color rojo. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) El valor de atributo de expresión `:v_sub` es un marcador de posición para `Red`. | 
|  `size (path)`  | Devuelve un número que representa el tamaño de un atributo. A continuación se muestran los tipos de datos válidos para usarlos con `size`.  Si el atributo es de tipo `String`, `size` devuelve la longitud de la cadena. Ejemplo: Comprobación de si la cadena `Brand` es menor o igual que 20 caracteres. El valor de atributo de expresión `:v_sub` es un marcador de posición para `20`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Si el atributo es de tipo `Binary`, `size` devuelve el número de bytes del valor del atributo. Ejemplo: supongamos que el elemento `ProductCatalog` tiene un atributo binario denominado `VideoClip` que contiene vídeo breve sobre el uso del producto. En la siguiente expresión se comprueba si `VideoClip` supera los 64 000 bytes. El valor de atributo de expresión `:v_sub` es un marcador de posición para `64000`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Si el tipo de datos del atributo es `Set`, `size` devuelve el número de componentes del conjunto.  Ejemplo: Comprobación de si el producto está disponible en más de un color. El valor de atributo de expresión `:v_sub` es un marcador de posición para `1`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  Si el atributo es de tipo `List` o `Map`, `size` devuelve el número de componentes secundarios. Ejemplo: Comprobación de si el número de opiniones `OneStar` ha superado un umbral determinado. El valor de atributo de expresión `:v_sub` es un marcador de posición para `3`. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 

## Evaluaciones lógicas
<a name="Expressions.OperatorsAndFunctions.LogicalEvaluations"></a>

Utilice las palabras clave `AND`, `OR` y `NOT` para llevar a cabo evaluaciones lógicas. En la lista siguiente, *a* y *b* representan las condiciones que se van a evaluar.
+ `a AND b`: es true si *a* y *b* son true.
+ `a OR b`: es true si *a* o *b* (o ambas) son true.
+ `NOT a`: es true si *a* es false. False si *a* es true.

A continuación se muestra un ejemplo de código de AND en una operación.

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

## Paréntesis
<a name="Expressions.OperatorsAndFunctions.Parentheses"></a>

Los paréntesis se utilizan para cambiar la preferencia de una evaluación lógica. Por ejemplo, supongamos que las condiciones *a* y *b* son true y que la condición *c* es false. La siguiente expresión se evalúa en true:
+ `a OR b AND c`

Sin embargo, si se incluye una condición entre paréntesis, esta se evalúa antes. Por ejemplo, lo siguiente se evalúa en false:
+  `(a OR b) AND c`

**nota**  
En una expresión se pueden utilizar paréntesis anidados. En este caso, se evalúan primero los más internos.

A continuación se muestra un ejemplo de código con paréntesis en una evaluación lógica.

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

## Precedencia en las condiciones
<a name="Expressions.OperatorsAndFunctions.Precedence"></a>

 DynamoDB evalúa las condiciones de izquierda a derecha aplicando las siguientes normas de prioridad:
+ `= <> < <= > >=`
+ `IN`
+ `BETWEEN`
+ `attribute_exists attribute_not_exists begins_with contains`
+ Paréntesis
+ `NOT`
+ `AND`
+ `OR`

# Ejemplo de la CLI de expresión de condición de DynamoDB
<a name="Expressions.ConditionExpressions"></a>

A continuación se muestran algunos ejemplos de uso de expresiones de condición en la AWS Command Line Interface (AWS CLI). Estos ejemplos se basan en la tabla `ProductCatalog`, especificada en [Referencia a atributos de elementos mediante expresiones en DynamoDB](Expressions.Attributes.md). La clave de partición de esta tabla es `Id` y no tiene clave de ordenación. La siguiente operación `PutItem` crea un elemento de muestra `ProductCatalog` al que se refieren los ejemplos.

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

Los argumentos de `--item` se almacenan en el archivo `item.json`. Para simplificar, se utilizan tan solo algunos de los atributos de elementos.

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

**Topics**
+ [PUT condicional](#Expressions.ConditionExpressions.PreventingOverwrites)
+ [Eliminaciones condicionales](#Expressions.ConditionExpressions.AdvancedComparisons)
+ [Actualizaciones condicionales](#Expressions.ConditionExpressions.SimpleComparisons)
+ [Ejemplos de expresiones condicionales](#Expressions.ConditionExpressions.ConditionalExamples)

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

La operación `PutItem` sobrescribe un elemento que tenga la misma clave principal (si existe). Si desea evitar que esto suceda, utilice una expresión de condición. Esto permite que la escritura se lleve a cabo solo si el elemento en cuestión ya no tiene la misma clave principal.

En el siguiente ejemplo se utiliza `attribute_not_exists()` para comprobar si la clave principal existe en la tabla antes de intentar la operación de escritura. 

**nota**  
Si la clave principal consta de una clave de partición (pk) y una clave de clasificación (sk), el parámetro comprobará si `attribute_not_exists(pk)` Y `attribute_not_exists(sk)` se evalúan como verdadero o falso como una instrucción completa antes de intentar la operación de escritura.

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

Si la expresión de condición se evalúa en false (falso), DynamoDB devuelve el siguiente mensaje de error: The conditional request failed (Se produjo un error en la consulta condicional).

**nota**  
Para obtener más información sobre `attribute_not_exists` y otras funciones, consulte [Expresiones, operadores y funciones de condición y filtro en DynamoDB](Expressions.OperatorsAndFunctions.md).

## Eliminaciones condicionales
<a name="Expressions.ConditionExpressions.AdvancedComparisons"></a>

Para realizar una eliminación condicional, se usa una operación `DeleteItem` con una expresión de condición. La expresión de condición debe evaluarse en true para que la operación se lleve a cabo correctamente; de lo contrario, se produce un error.

Tenga en cuenta el elemento definido anteriormente.

Suponga que desea eliminar el elemento, pero solo en las siguientes condiciones:
+  El valor de `ProductCategory` es "Sporting Goods" o "Gardening Supplies".
+  El valor de `Price` está comprendido entre 500 y 600.

En el siguiente ejemplo se intenta eliminar el elemento.

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

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

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

**nota**  
En la expresión de condición, `:` (signo de dos puntos) indica un *valor de atributo de expresión* (un marcador de posición del valor real). Para obtener más información, consulte [Uso de valores de atributos de expresión en DynamoDB](Expressions.ExpressionAttributeValues.md).  
Para obtener más información sobre `IN`, `AND` y otras palabras clave, consulte [Expresiones, operadores y funciones de condición y filtro en DynamoDB](Expressions.OperatorsAndFunctions.md).

En este ejemplo, la comparación de `ProductCategory` se evalúa en true, pero la comparación de `Price` se evalúa en false. Esto hace que la expresión de condición se evalúe en false y, por consiguiente, la operación `DeleteItem` no se lleva a cabo.

## Actualizaciones condicionales
<a name="Expressions.ConditionExpressions.SimpleComparisons"></a>

Para realizar una actualización condicional, se usa una operación `UpdateItem` con una expresión de condición. La expresión de condición debe evaluarse en true para que la operación se lleve a cabo correctamente; de lo contrario, se produce un error.

**nota**  
`UpdateItem` también admite las *expresiones de actualización*, donde especifica las modificaciones que se desea aplicar a un elemento. Para obtener más información, consulte [Uso de expresiones de actualización en DynamoDB](Expressions.UpdateExpressions.md).

Supongamos que ha comenzado por el elemento definido anteriormente.

En el ejemplo siguiente se realiza una operación `UpdateItem`. Se intenta reducir el valor de `Price` de un producto en 75, pero la expresión de condición impide la actualización si el valor de `Price` actual es menor o igual que 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
```

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

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

Si el valor inicial de `Price` es 650, la operación `UpdateItem` reduce el `Price` a 575. Si ejecuta la operación `UpdateItem` de nuevo, el valor de `Price` se reduce a 500. Si se ejecuta una tercera vez, la expresión de condición se evalúa en false y la actualización no se lleva a cabo.

**nota**  
En la expresión de condición, `:` (signo de dos puntos) indica un *valor de atributo de expresión* (un marcador de posición del valor real). Para obtener más información, consulte [Uso de valores de atributos de expresión en DynamoDB](Expressions.ExpressionAttributeValues.md).  
Para obtener más información sobre "*>*" y otros operadores, consulte [Expresiones, operadores y funciones de condición y filtro en DynamoDB](Expressions.OperatorsAndFunctions.md).

## Ejemplos de expresiones condicionales
<a name="Expressions.ConditionExpressions.ConditionalExamples"></a>

Para obtener más información acerca de las funciones utilizadas en los ejemplos siguientes, consulte [Expresiones, operadores y funciones de condición y filtro en DynamoDB](Expressions.OperatorsAndFunctions.md). Si desea obtener más información sobre cómo especificar distintos tipos de atributo en una expresión, consulte [Referencia a atributos de elementos mediante expresiones en DynamoDB](Expressions.Attributes.md). 

### Comprobación de los atributos de un elemento
<a name="Expressions.ConditionExpressions.CheckingForAttributes"></a>

Puede comprobar la existencia (o inexistencia) de cualquier atributo. Si la expresión de condición se evalúa en true, entonces la operación se realiza correctamente; de lo contrario, produce un error.

En el siguiente ejemplo se utiliza `attribute_not_exists` para eliminar un producto únicamente si no tiene el atributo `Price`.

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

DynamoDB también proporciona un función `attribute_exists`. En el siguiente ejemplo se elimina un producto únicamente si ha recibido opiniones negativas.

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

### Comprobación del tipo de atributo
<a name="Expressions.ConditionExpressions.CheckingForAttributeType"></a>

Puede comprobar el tipo de datos de un valor de atributo mediante la función `attribute_type`. Si la expresión de condición se evalúa en true, entonces la operación se realiza correctamente; de lo contrario, produce un error.

En el ejemplo siguiente se utiliza `attribute_type` para eliminar un producto sólo si tiene un atributo `Color` de tipo String Set. 

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

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

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

### Comprobación del valor inicial de cadena
<a name="Expressions.ConditionExpressions.CheckingBeginsWith"></a>

Puede comprobar si un valor de atributo String comienza con una subcadena determinada mediante la función `begins_with`. Si la expresión de condición se evalúa en true, entonces la operación se realiza correctamente; de lo contrario, produce un error. 

En el ejemplo siguiente se utiliza `begins_with` para eliminar un producto solo si el elemento `FrontView` del mapa `Pictures` comienza con un 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
```

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

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

### Comprobación de un elemento en un conjunto
<a name="Expressions.ConditionExpressions.CheckingForContains"></a>

Puede buscar un elemento en un conjunto o buscar una subcadena dentro de una cadena mediante el uso de la función `contains`. Si la expresión de condición se evalúa en true, entonces la operación se realiza correctamente; de lo contrario, produce un error. 

En el ejemplo siguiente se utiliza `contains` para eliminar un producto sólo si el conjunto de cadenas `Color` tiene un elemento con un 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
```

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

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

### Comprobación del tamaño de un valor de atributo
<a name="Expressions.ConditionExpressions.CheckingForSize"></a>

Puede comprobar el tamaño de un valor de atributo mediante la función `size`. Si la expresión de condición se evalúa en true, entonces la operación se realiza correctamente; de lo contrario, produce un error. 

En el ejemplo siguiente se utiliza `size` para eliminar un producto sólo si el tamaño del atributo Binary `VideoClip` es mayor de `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
```

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

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

# Uso del período de vida (TTL) en DynamoDB
<a name="TTL"></a>

Tiempo de vida (TTL) para DynamoDB es un método rentable para eliminar elementos que ya no son relevantes. TTL permite definir una marca de tiempo de vencimiento por elemento que indica cuándo deja de necesitarse un elemento. DynamoDB elimina automáticamente los elementos vencidos a los pocos días de su fecha de vencimiento, sin afectar al rendimiento de escritura. 

Para usar TTL, primero debe activarlo en una tabla y, a continuación, definir un atributo específico para almacenar la marca de tiempo de vencimiento de TTL. La marca de tiempo debe almacenarse como un tipo de datos de [Número](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes) en [formato de tiempo Epoch de Unix](https://en.wikipedia.org/wiki/Unix_time) con nivel de precisión de segundos. El proceso TTL ignora los elementos con un atributo TTL que no sea un tipo de número. Cada vez que se crea o actualiza un elemento, puede calcular el tiempo de vencimiento y guardarlo en el atributo TTL.

El sistema puede eliminar los elementos con atributos TTL válidos y vencidos en cualquier momento, normalmente a los pocos días de que hayan caducado. Puede seguir actualizando los elementos vencidos que no se hayan eliminado todavía, lo que incluye cambiar o eliminar los atributos TTL. Al actualizar un elemento vencido, le recomendamos que utilice una expresión de condición para asegurarse de que el elemento no se haya eliminado posteriormente. Utilice expresiones de filtro para eliminar los elementos vencidos de los resultados de [Scan](Scan.md#Scan.FilterExpression) y [Query](Query.FilterExpression.md).

Los elementos eliminados funcionan de forma similar a los que se eliminan con las operaciones de eliminación habituales. Una vez eliminados, los elementos pasan a DynamoDB Streams como eliminaciones de servicio en lugar de eliminaciones de usuario. Además, se eliminan de los índices secundarios locales y de los índices secundarios globales de igual modo que con las otras operaciones de eliminación. 

Si usa la [versión 2019.11.21 (actual) de las tablas globales](GlobalTables.md) y también la característica TTL, DynamoDB replicará las eliminaciones de TTL en todas las tablas de réplica. La eliminación de TTL inicial no consume unidades de capacidad de escritura (WCU) en la región donde se produce el vencimiento de TTL. Sin embargo, la eliminación de TTL replicada en las tablas de réplica consume una unidad de capacidad de escritura replicada cuando se usa la capacidad aprovisionada, o una unidad de escritura replicada cuando se usa el modo de capacidad bajo demanda, en cada una de las regiones de réplica. En estos casos, se aplicarán los cargos pertinentes.

Para obtener más información acerca de TTL, consulte estos temas:

**Topics**
+ [Habilitación del período de vida (TTL) de DynamoDB](time-to-live-ttl-how-to.md)
+ [Período de vida (TTL) de computación en DynamoDB](time-to-live-ttl-before-you-start.md)
+ [Uso de elementos caducados y el período de vida (TTL)](ttl-expired-items.md)

# Habilitación del período de vida (TTL) de DynamoDB
<a name="time-to-live-ttl-how-to"></a>

**nota**  
Para facilitar la depuración y la verificación del correcto funcionamiento de la característica TTL, los valores proporcionados para el TTL de un elemento se registran en texto no cifrado en los registros de diagnóstico de DynamoDB.

Puede habilitar TTL en la consola de Amazon DynamoDB, la AWS Command Line Interface (AWS CLI) o mediante la [referencia de la API de Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/) con cualquiera de los AWS SDK supuestos. La habilitación de TTL en todas las particiones tarda aproximadamente una hora.

## Activación del TTL de DynamoDB mediante la consola de AWS
<a name="time-to-live-ttl-how-to-enable-console"></a>

1. Inicie sesión en la Consola de administración de AWS y abra la consola de DynamoDB en [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. Elija **Tables (Tablas)** y, a continuación, seleccione la tabla que desee modificar.

1. En la pestaña **Configuración adicional**, dentro de la sección **Tiempo de vida (TTL)**, elija **Activar**.

1. Al habilitar TTL en una tabla, DynamoDB requiere que identifique un nombre de atributo específico que el servicio buscará al determinar si un elemento cumple los requisitos para el vencimiento. El nombre del atributo TTL, que se muestra a continuación, distingue entre mayúsculas y minúsculas y debe coincidir con el atributo definido en las operaciones de lectura y escritura. Si no coinciden, los elementos caducados no se eliminarán. Si se cambia el nombre del atributo TTL, deberá desactivarse el TTL y volverse a activar con el nuevo atributo de ahora en adelante. Una vez desactivado, el TTL seguirá procesando las eliminaciones durante aproximadamente 30 minutos. El TTL debe reconfigurarse en las tablas restauradas.  
![\[Nombre de atributo TTL que distingue entre mayúsculas y minúsculas que DynamoDB utiliza para determinar si un artículo puede caducar.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/EnableTTL-Settings.png)

1. (Opcional) Puede realizar una prueba simulando la fecha y la hora de vencimiento y haciendo coincidir algunos elementos. Al hacer se muestra una lista de elementos de ejemplo donde se confirma que hay elementos que contienen el nombre del atributo TTL junto con la fecha de vencimiento.

Ahora que TTL está activado, el atributo TTL llevará la marca **TTL** cuando consulte los elementos en la consola de DynamoDB. Para ver la fecha y la hora de vencimiento de un elemento, mantenga el cursor del ratón sobre el atributo. 

## Activación del TTL de DynamoDB mediante la API
<a name="time-to-live-ttl-how-to-enable-api"></a>

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

Puede activar el TTL con código con la operación [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')
```

Puede confirmar que el TTL está activado mediante la operación [DescribeTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/describe_time_to_live.html), que describe el estado del TTL en una tabla. El estado de `TimeToLive` es `ENABLED` o `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 ]

Puede activar el TTL con código con la operación [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');
```

------

## Activación del tiempo de vida mediante la AWS CLI
<a name="time-to-live-ttl-how-to-enable-cli-sdk"></a>

1. Habilite TTL en la tabla `TTLExample`.

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

1. Describa TTL en la tabla `TTLExample`.

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

1. Añada un elemento a la tabla `TTLExample` con el atributo de período de vida establecido utilizando el shell de BASH y la AWS CLI. 

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

Este ejemplo comienza con la fecha actual y añade cinco días para crear una fecha de vencimiento. A continuación, convierte la fecha de vencimiento al formato de tiempo Unix y, por último, agrega un elemento a la tabla "`TTLExample`". 

**nota**  
 Una forma de establecer valores de vencimiento para período de vida consiste en calcular el número de segundos que se sumarán al momento del vencimiento. Por ejemplo, 5 días son 432 000 segundos. Sin embargo, a menudo es preferible comenzar por una fecha y tomarla como punto de partida.

Es bastante sencillo obtener el tiempo actual en formato de tiempo Unix, como en los siguientes ejemplos.
+ Terminal Linux: `date +%s`
+ Python: `import time; int(time.time())`
+ Java: `System.currentTimeMillis() / 1000L`
+ JavaScript: : `Math.floor(Date.now() / 1000)`

## Activación del TTL de DynamoDB mediante 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
```

Puede encontrar [aquí](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-table-timetolivespecification.html) más información sobre el uso del TTL en las plantillas de CloudFormation.

# Período de vida (TTL) de computación en DynamoDB
<a name="time-to-live-ttl-before-you-start"></a>

Una forma habitual de implementar el TTL consiste en establecer una fecha de vencimiento para los elementos en función de cuándo se crearon o se actualizaron por última vez. Esto se puede hacer añadiendo la hora a las marcas de tiempo `createdAt` y `updatedAt`. Por ejemplo, el TTL de los elementos que se acaban de crear se puede establecer en `createdAt` más 90 días. Cuando se actualiza el elemento, el TTL se puede volver a calcular como `updatedAt` más de 90 días.

El tiempo de vencimiento calculado debe estar en formato Epoch, expresado en segundos. Para que se tenga en cuenta el vencimiento y la eliminación, el TTL no puede tener más de cinco años de antigüedad. Si utiliza cualquier otro formato, los procesos de TTL ignoran el elemento. Si establece la fecha de vencimiento en algún momento futuro en el que desee que el artículo caduque, este caducará una vez transcurrido ese plazo. Por ejemplo, supongamos que establece la fecha de vencimiento en 1724241326 (que corresponde al lunes 21 de agosto de 2024 a las 11:55:26 [UTC]). El elemento vence cuando se alcanza la fecha especificada. No hay una duración mínima de TTL. Puede establecer la fecha de vencimiento en cualquier momento futuro, por ejemplo, 5 minutos a partir de la hora actual. Sin embargo, DynamoDB suele eliminar los elementos caducados en un plazo de 48 horas tras su fecha de vencimiento, y no inmediatamente después de que caduquen.

**Topics**
+ [Creación de un elemento y determinación del tiempo de vida](#time-to-live-ttl-before-you-start-create)
+ [Actualización de un elemento y del tiempo de vida](#time-to-live-ttl-before-you-start-update)

## Creación de un elemento y determinación del tiempo de vida
<a name="time-to-live-ttl-before-you-start-create"></a>

En el siguiente ejemplo se muestra cómo calcular el tiempo de vencimiento al crear un elemento nuevo, utilizando `expireAt` como nombre de atributo TTL. Una instrucción de asignación obtiene la hora actual como variable. En el ejemplo, la fecha de vencimiento se calcula en 90 días a partir de la fecha actual. A continuación, la fecha se convierte al formato Epoch y se guarda como un tipo de dato entero en el atributo TTL.

Los siguientes ejemplos de código muestran cómo crear un elemento con 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;
        }
    }
}
```
+  Para obtener información sobre la API, consulte [PutItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/PutItem) en la *referencia de la API de 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');
```
+  Para obtener información sobre la API, consulte [PutItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/PutItemCommand) en la *referencia de la API de 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"
)
```
+  Para obtener información sobre la API, consulte [PutItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/PutItem) en la *referencia de la API de AWS SDK para Python (Boto3)*. 

------

## Actualización de un elemento y del tiempo de vida
<a name="time-to-live-ttl-before-you-start-update"></a>

Este ejemplo es la continuación del que aparece en la [sección anterior](#time-to-live-ttl-before-you-start-create). La fecha de vencimiento se puede volver a calcular si se actualiza el elemento. En el siguiente ejemplo, se vuelve a calcular la marca de tiempo `expireAt` para que sea de 90 días a partir de la fecha actual.

En los siguientes ejemplos de código, se muestra cómo actualizar el TTL de un elemento.

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

**SDK para Java 2.x**  
Actualice el TTL en un elemento de DynamoDB existente en una tabla.  

```
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;
        }
    }
```
+  Para obtener información sobre la API, consulte [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem) en la *referencia de la API de 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');
```
+  Para obtener información sobre la API, consulte [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand) en la *referencia de la API de 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"
)
```
+  Para obtener información la API, consulte [UpdateItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem) en la *referencia de la API de AWS SDK para Python (Boto3)*. 

------

Los ejemplos de TTL que se analizan en esta introducción muestran un método para garantizar que en la tabla solo se guarden los elementos actualizados recientemente. La vida útil de los elementos actualizados se prolonga, mientras que los que no se actualizan tras su creación caducan y se eliminan sin costo alguno, lo que reduce el almacenamiento y mantiene las tablas limpias.

# Uso de elementos caducados y el período de vida (TTL)
<a name="ttl-expired-items"></a>

Los elementos vencidos que aún deben eliminarse se pueden filtrar de las operaciones de lectura y escritura. Esto resulta útil en situaciones en las que los datos vencidos ya no son válidos y no deben utilizarse. Si no están filtrados, seguirán mostrándose en las operaciones de lectura y escritura hasta que se eliminen en el proceso en segundo plano.

**nota**  
Estos elementos seguirán contabilizándose para los costos de almacenamiento y lectura hasta que se eliminen.

Las eliminaciones de TTL se pueden identificar en DynamoDB Streams, pero solo en la región en la que se han eliminado. Las eliminaciones de TTL que se replican en las regiones de la tabla global no se pueden identificar en las transmisiones de DynamoDB de las regiones en las que se replica la eliminación.

## Filtrado de los elementos vencidos de las operaciones de lectura
<a name="ttl-expired-items-filter"></a>

Para las operaciones de lectura, como [Scan](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) y [Query](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html), una expresión de filtro puede filtrar los elementos vencidos que aún no se han eliminado. Como se muestra en el siguiente fragmento de código, la expresión de filtro puede filtrar los elementos en los que el tiempo de TTL sea igual o inferior al tiempo actual. Por ejemplo, el código del SDK de Python incluye una declaración de asignación que obtiene la hora actual como una variable (`now`) y la convierte en `int` para el formato de tiempo Epoch.

En los siguientes ejemplos de código, se muestra cómo consultar elementos de TTL.

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

**SDK para Java 2.x**  
Consulte una expresión filtrada para recopilar elementos de TTL en una tabla de DynamoDB mediante 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;
        }
```
+  Para obtener información sobre la API, consulte [Query](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/Query) en la *referencia de la API de AWS SDK for Java 2.x*. 

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

**SDK para JavaScript (v3)**  
Consulte una expresión filtrada para recopilar elementos de TTL en una tabla de DynamoDB mediante 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');
```
+  Para obtener información sobre la API, consulte [Query](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/QueryCommand) en la *referencia de la API de AWS SDK para JavaScript*. 

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

**SDK para Python (Boto3)**  
Consulte una expresión filtrada para recopilar elementos de TTL en una tabla de DynamoDB mediante 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")
```
+  Para obtener información sobre la API, consulte [Query](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/Query) en la *referencia de la API de AWS SDK para Python (Boto3)*. 

------

## Escritura condicional en los elementos vencidos
<a name="ttl-expired-items-conditional-write"></a>

Se puede usar una expresión condicional para evitar escrituras en los elementos vencidos. El siguiente fragmento de código es una actualización condicional que comprueba si el tiempo de vencimiento es superior al tiempo actual. Si es verdadero, la operación de escritura continuará.

En los siguientes ejemplos de código se muestra cómo actualizar de forma condicional el TTL de un elemento.

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

**SDK para Java 2.x**  
Actualice el TTL en un elemento de DynamoDB existente en una tabla con una condición.  

```
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;
        }
    }
}
```
+  Para obtener información sobre la API, consulte [UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem) en la *referencia de la API de AWS SDK for Java 2.x*. 

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

**SDK para JavaScript (v3)**  
Actualice el TTL en un elemento de DynamoDB existente en una tabla con una condición.  

```
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');
```
+  Para obtener información sobre la API, consulte [UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand) en la *referencia de la API de AWS SDK para JavaScript*. 

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

**SDK para Python (Boto3)**  
Actualice el TTL en un elemento de DynamoDB existente en una tabla con una condición.  

```
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",
)
```
+  Para obtener información la API, consulte [UpdateItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem) en la *referencia de la API de AWS SDK para Python (Boto3)*. 

------

## Identificación de elementos eliminados en DynamoDB Streams
<a name="ttl-expired-items-identifying"></a>

El registro de secuencias contiene el campo de identidad del usuario `Records[<index>].userIdentity`. Los elementos que elimina el proceso TTL tienen los campos siguientes:

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

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

En el código JSON siguiente se muestra la parte pertinente de un registro de secuencias único:

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

# Consulta de tablas en DynamoDB
<a name="Query"></a>

Puede usar la operación de la API `Query` en Amazon DynamoDB para buscar elementos según los valores de clave principal.

Debe proporcionar el nombre del atributo de clave de partición y un único valor para dicho atributo. `Query` devuelve todos los elementos que contengan ese valor de clave de partición. Si lo desea, puede proporcionar un atributo de clave de ordenación y utilizar un operador de comparación para limitar los resultados de búsqueda.

Para obtener más información sobre cómo usar `Query`, como la sintaxis de la solicitud, los parámetros de respuesta y ejemplos adicionales, consulte [Query](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) en la *Referencia de la API de Amazon DynamoDB*.

**Topics**
+ [Expresiones de condición de clave para la operación Query en DynamoDB](Query.KeyConditionExpressions.md)
+ [Expresiones de filtro para la operación Query en DynamoDB](Query.FilterExpression.md)
+ [Paginación de los resultados de consulta de tabla en DynamoDB](Query.Pagination.md)
+ [Otros aspectos del trabajo con la operación Query en DynamoDB](Query.Other.md)

# Expresiones de condición de clave para la operación Query en DynamoDB
<a name="Query.KeyConditionExpressions"></a>

Puede utilizar cualquier nombre de atributo en una expresión de condición de clave, siempre y cuando el primer carácter sea `a-z` o `A-Z` y el resto de los caracteres (a partir del segundo carácter, si lo hay) sea `a-z`, `A-Z` o `0-9`. Además, el nombre de atributo no debe ser una palabra reservada de DynamoDB. Para obtener una lista completa de estas palabras, consulte . [Palabras reservadas en DynamoDB](ReservedWords.md).) Si un nombre de atributo no cumple estos requisitos, debe definir un nombre de atributo de expresión como marcador de posición. Para obtener más información, consulte [Nombres de atributos de expresión (Alias) en DynamoDB](Expressions.ExpressionAttributeNames.md).

DynamoDB almacena cerca unos de otros y ordenados según su clave de ordenación aquellos elementos que tienen un valor de clave de partición determinado. En una operación `Query`, DynamoDB recupera los elementos de forma ordenada y, a continuación, los procesa mediante las expresiones `KeyConditionExpression` y `FilterExpression` que estén presentes. Solo entonces devuelve los resultados de `Query` al cliente.

Una operación `Query` siempre devuelve un conjunto de resultados. Si no se encuentran elementos coincidentes, el conjunto de resultados está vacío.

`Query`Los resultados de siempre se ordenan según el valor de la clave de ordenación. Si el tipo de datos de la clave de ordenación es `Number`, los resultados se devuelven en orden numérico. De lo contrario, los resultados se devuelven según el orden de los bytes UTF-8. De forma predeterminada, el orden es ascendente. Para invertirlo, establezca el parámetro `ScanIndexForward` en `false`.

En una sola operación `Query` se puede recuperar un máximo de 1 MB de datos. Este límite se aplica antes de que `FilterExpression` o `ProjectionExpression` se apliquen a los resultados. Si `LastEvaluatedKey` está presente en la respuesta y su valor no es null, debe paginar el conjunto de resultados (consulte [Paginación de los resultados de consulta de tabla en DynamoDB](Query.Pagination.md)).

## Ejemplos de expresión de condición de clave
<a name="Query.KeyConditionExpressions-example"></a>

Para especificar los criterios de búsqueda, se utiliza una *expresión de condición de clave*; se trata de una cadena que determina los elementos que se van a leer en la tabla o el índice.

Debe especificar el nombre y valor de la clave de partición como una condición de igualdad. No puede utilizar un atributo no clave en una expresión de condición clave.

Si lo desea, puede proporcionar una segunda condición para la clave de ordenación (en caso de incluirse). En la condición de clave de ordenación se debe utilizar uno de los siguientes operadores de comparación:
+ `a = b`: es true si el atributo *a* es igual al valor *b*.
+ `a < b`: es true si *a* es menor que *b*.
+ `a <= b`: es true si *a* es menor o igual que *b*.
+ `a > b`: es true si *a* es mayor que *b*.
+ `a >= b`: es true si *a* es mayor o igual que *b*.
+ `a BETWEEN b AND c`: es true si *a* es mayor o igual que *b* y menor o igual que *c*.

También se admite la siguiente función:
+ `begins_with (a, substr)`: es true si el valor del atributo `a` comienza por una subcadena determinada.

En los siguientes ejemplos de la AWS Command Line Interface (AWS CLI) se muestra el uso de expresiones de condición de clave. Estas expresiones utilizan marcadores de posición (como `:name` y `:sub`) en lugar de los valores reales. Para obtener más información, consulte [Nombres de atributos de expresión (Alias) en DynamoDB](Expressions.ExpressionAttributeNames.md) y [Uso de valores de atributos de expresión en DynamoDB](Expressions.ExpressionAttributeValues.md).

**Example**  
Consulta la tabla `Thread` para buscar un valor concreto de `ForumName` (clave de partición). La consulta leerá todos los elementos que tengan ese valor de `ForumName`, porque la clave de ordenación (`Subject`) no se incluye en `KeyConditionExpression`.  

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

**Example**  
Consulta la tabla `Thread` para buscar un valor concreto de `ForumName` (clave de partición), pero esta vez devuelve solo los elementos que tienen un valor determinado de `Subject` (clave de ordenación).  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :name and Subject = :sub" \
    --expression-attribute-values  file://values.json
```
Los argumentos de `--expression-attribute-values` se almacenan en el archivo `values.json`.  

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

**Example**  
Consulta la tabla `Reply` para buscar un valor concreto de `Id` (clave de partición), pero solo devuelve los elementos cuyo valor de `ReplyDateTime` (clave de ordenación) comienza por determinados caracteres.  

```
aws dynamodb query \
    --table-name Reply \
    --key-condition-expression "Id = :id and begins_with(ReplyDateTime, :dt)" \
    --expression-attribute-values  file://values.json
```
Los argumentos de `--expression-attribute-values` se almacenan en el archivo `values.json`.  

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

# Expresiones de filtro para la operación Query en DynamoDB
<a name="Query.FilterExpression"></a>

Si tiene que refinar más los resultados de `Query`, si lo desea puede indicar una expresión de filtro. Una *expresión de filtro* determina qué elementos de los resultados de `Query` se deben devolver al usuario. Todos los demás resultados se descartan.

Una expresión de filtro se aplica después de que la operación `Query` haya finalizado, pero antes de devolver los resultados. Por consiguiente, `Query` consume la misma cantidad de capacidad de lectura aunque se especifique una expresión de filtro.

En una operación `Query` se puede recuperar un máximo de 1 MB de datos. Este límite se aplica antes de evaluar la expresión de filtro.

Una expresión de filtro no puede contener atributos de clave de partición ni de clave de ordenación. Esos atributos se deben especificar en la expresión de condición de clave, no en la expresión de filtro.

La sintaxis de una expresión de filtro es similar a la de una expresión de condición de clave. Las expresiones de filtro pueden utilizar los mismos comparadores, funciones y operadores lógicos que las expresiones de condición de clave. Además, las expresiones de filtro pueden usar los operadores “no es igual” (`<>`), `OR`, `CONTAINS`, `IN`, `BEGINS_WITH`, `BETWEEN`, `EXISTS` y `SIZE`. Para obtener más información, consulte [Expresiones de condición de clave para la operación Query en DynamoDB](Query.KeyConditionExpressions.md) y [Sintaxis de las expresiones de filtro y condición](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Syntax).

**Example**  
En el siguiente ejemplo de la AWS CLI, se consulta la tabla `Thread` para buscar un valor concreto de `ForumName` (clave de partición) y `Subject` (clave de ordenación). De los elementos encontrados, solo se devuelven las conversaciones más populares; es decir, solo aquellas que tienen un valor de mayor que el número especificado `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
```
Los argumentos de `--expression-attribute-values` se almacenan en el archivo `values.json`.  

```
{
    ":fn":{"S":"Amazon DynamoDB"},
    ":sub":{"S":"DynamoDB Thread 1"},
    ":num":{"N":"3"}
}
```
Tenga en cuenta que `Views` es una palabra reservada en DynamoDB (consulte [Palabras reservadas en DynamoDB](ReservedWords.md)), por lo que en este ejemplo se utiliza `#v` como marcador de posición. Para obtener más información, consulte [Nombres de atributos de expresión (Alias) en DynamoDB](Expressions.ExpressionAttributeNames.md).

**nota**  
Una expresión de filtro elimina los elementos del conjunto de resultados de `Query`. Si es posible, evite usar `Query` cuando prevea que va a recuperar gran cantidad de elementos, pero que tendrá que descartar la mayoría de ellos.

# Paginación de los resultados de consulta de tabla en DynamoDB
<a name="Query.Pagination"></a>

DynamoDB *pagina* los resultados de las operaciones `Query`. La paginación permite dividir los resultados de `Query` en "páginas" de datos con un tamaño de 1 MB (o menos). Una aplicación puede procesar la primera página de resultados, luego la segunda página, y así sucesivamente.

Una operación `Query` única devuelve solamente un conjunto de resultados que se ajuste al límite de tamaño de 1 MB. Para determinar si hay más resultados y para recuperarlos de página en página, las aplicaciones deben hacer lo siguiente: 

1. Examinar el resultado de `Query` de bajo nivel:
   + Si el resultado contiene una entrada `LastEvaluatedKey`, vaya al paso 2.
   + Si *no* figura `LastEvaluatedKey` en el resultado, no hay más elementos que recuperar.

1. Construya una `Query` con la misma `KeyConditionExpression`. Sin embargo, esta vez, se toma el valor `LastEvaluatedKey` del paso 1 y se usa como parámetro `ExclusiveStartKey` en la nueva solicitud `Query`.

1. Ejecutar la nueva solicitud `Query`.

1. Ir al paso 1.

Es decir, el valor de `LastEvaluatedKey` de la respuesta de `Query` debe utilizarse como valor de `ExclusiveStartKey` en la siguiente solicitud `Query`. Si no hay una entrada `LastEvaluatedKey` en una respuesta de `Query`, significa que se ha recuperado la última página de resultados. Si `LastEvaluatedKey` no está vacía, no significa necesariamente que haya más datos en el conjunto de resultados. La única forma de saber que se ha alcanzado el final del conjunto de resultados es cuando `LastEvaluatedKey` está vacío.

Puede utilizar la AWS CLI para ver este comportamiento. La AWS CLI envía solicitudes `Query` de bajo nivel a DynamoDB una y otra vez hasta que `LastEvaluatedKey` ya no esté presente en los resultados. Considere el siguiente ejemplo de la AWS CLI que recupera títulos de películas de un determinado año:

```
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, la AWS CLI se encarga de la paginación automáticamente. No obstante, en este ejemplo, el parámetro AWS CLI de la `--page-size` limita el número de elementos por página. El parámetro `--debug` muestra información de bajo nivel de las solicitudes y las respuestas.

Si ejecuta el ejemplo, la primera respuesta de DynamoDB será similar a la siguiente.

```
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}'
```

El elemento `LastEvaluatedKey` de la respuesta indica que no se han recuperado todos los elementos. La AWS CLI envía entonces otra solicitud `Query` a DynamoDB. Este patrón de solicitud y respuesta continúa hasta la respuesta 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}'
```

La ausencia de `LastEvaluatedKey` indica que no hay más elementos que recuperar.

**nota**  
Los SDK de AWS se encargan también de las respuestas de DynamoDB de bajo nivel (incluida la presencia o ausencia de `LastEvaluatedKey`) y proporcionan varias abstracciones para paginar los resultados de `Query`. Por ejemplo, la interfaz de documentos de SDK para Java proporciona compatibilidad con `java.util.Iterator` para que pueda examinar los resultados de uno en uno.  
Para ver ejemplos de código en diversos lenguajes de programación, consulte la [Guía de inicio de Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/) y la documentación del SDK de AWS correspondiente a su lenguaje.

También puede reducir el tamaño de página limitando el número de elementos del conjunto de resultados, con el parámetro de `Limit` de la operación de `Query`.

Para obtener más información sobre cómo realizar consultas en DynamoDB, consulte [Consulta de tablas en DynamoDB](Query.md).

# Otros aspectos del trabajo con la operación Query en DynamoDB
<a name="Query.Other"></a>

En esta sección se tratan aspectos adicionales de la operación Query de DynamoDB, como la limitación del tamaño del resultado, el recuento de elementos analizados frente a los devueltos, la supervisión del consumo de capacidad de lectura y el control de la coherencia de lectura.

## Limitación del número de elementos del conjunto de resultados
<a name="Query.Limit"></a>

Con la operación `Query`, puede limitar el número de elementos que lee. Para ello, establezca el parámetro `Limit` en el número máximo de elementos que desee.

Por ejemplo, suponga que utiliza `Query` en una tabla con un valor de `Limit` de `6` y sin expresión de filtro. El resultado de `Query` contendrá los seis primeros elementos de la tabla que coincidan con la expresión de condición de clave de la solicitud.

Ahora, suponga que agrega una expresión de filtro a `Query`. En este caso, DynamoDB lee hasta seis elementos y, a continuación, devuelve solo aquellos que coinciden con la expresión de filtro. El resultado final de `Query` contiene seis elementos o menos, aunque más elementos hubieran coincidido con la expresión de filtro si DynamoDB hubiera seguido leyendo más elementos.

## Recuento de los elementos en los resultados
<a name="Query.Count"></a>

Además de los elementos que coinciden con los criterios, la respuesta de `Query` contiene las entradas siguientes:
+ `ScannedCount`: número de elementos que coinciden con la expresión de condición de clave *antes* de aplicar una expresión de filtro (si la hay).
+ `Count`: número de elementos restantes *después* de aplicar una expresión de filtro (si la hay).

**nota**  
Si no se utiliza una expresión de filtro, `ScannedCount` y `Count` tendrán el mismo valor.

Si el tamaño del conjunto de resultados de `Query` es mayor que 1 MB, entonces `ScannedCount` y `Count` representarán únicamente un recuento parcial de los elementos totales. Deberá llevar a cabo varias operaciones `Query` para recuperar todos los resultados (consulte [Paginación de los resultados de consulta de tabla en DynamoDB](Query.Pagination.md)).

Cada respuesta de `Query` contendrá los valores de `ScannedCount` y `Count` de los elementos que se han procesado en esa solicitud `Query` concreta. Para obtener totales globales para todas las solicitudes `Query`, puede llevar un recuento total de `ScannedCount` y `Count`.

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

Puede utilizar cualquier tabla o índice secundario `Query`, siempre que proporcione el nombre del atributo de clave de partición y un valor único para ese atributo. `Query` devuelve todos los elementos que contienen ese valor de clave de partición. Opcionalmente, puede proporcionar un atributo de clave de clasificación y utilizar un operador de comparación para limitar los resultados de la búsqueda. `Query` Las operaciones de la API consumen unidades de capacidad de lectura, como se indica a continuación.


****  

| Si `Query` se aplica a... | DynamoDB consume unidades de capacidad de lectura de... | 
| --- | --- | 
| Tabla | La capacidad de lectura aprovisionada de la tabla. | 
| Índice secundario global | La capacidad de lectura aprovisionada del índice. | 
| Índice secundario local | La capacidad de lectura aprovisionada de la tabla base. | 

De forma predeterminada, una operación `Query` no devuelve datos sobre la cantidad de capacidad de lectura que consume. Sin embargo, puede especificar el parámetro `ReturnConsumedCapacity` en una solicitud `Query` para obtener esta información. A continuación se muestran los ajustes válidos de `ReturnConsumedCapacity`:
+ `NONE`: no se devuelven datos de capacidad consumida. (Esta es la opción predeterminada.)
+ `TOTAL`: la respuesta incluye el número total de unidades de capacidad de lectura consumidas.
+ `INDEXES`: la respuesta muestra el número total de unidades de capacidad de lectura consumidas, así como la capacidad consumida de cada tabla e índice a los que se ha obtenido acceso.

DynamoDB calcula el número de unidades de capacidad de lectura consumidas según el número de elementos y el tamaño de dichos elementos, no según la cantidad de datos que se devuelven a una aplicación. Por este motivo, el número de unidades de capacidad consumidas es el mismo si se solicitan todos los atributos (el comportamiento predeterminado) o solo algunos de ellos (mediante una expresión de proyección). El número también es el mismo tanto si se utiliza una expresión de filtro como si no. `Query`consume una unidad de capacidad de lectura mínima para realizar una lectura altamente coherente por segundo o dos lecturas coherentes posteriores por segundo para un elemento de hasta 4 KB. Para leer un elemento mayor que 4 KB, DynamoDB necesita unidades de solicitud de lectura adicionales. Con las tablas vacías y las tablas muy grandes con una cantidad escasa de claves de partición, es posible que se cobren algunas RCU adicionales además de la cantidad de datos consultados. Esto cubre el costo de atender la solicitud `Query`, incluso si no hay datos.

## Coherencia de lectura para la consulta
<a name="Query.ReadConsistency"></a>

De forma predeterminada, una operación `Query` lleva a cabo lecturas consistentes finales. Esto significa que los resultados de `Query` podrían no reflejar los cambios provocados por operaciones `PutItem` o `UpdateItem` realizadas recientemente. Para obtener más información, consulte [Coherencia de lectura de DynamoDB](HowItWorks.ReadConsistency.md).

Si requiere lecturas de consistencia alta, establezca el parámetro `ConsistentRead` en `true` en la solicitud `Query`.

# Análisis de tablas en DynamoDB
<a name="Scan"></a>

Una operación `Scan` en Amazon DynamoDB lee todos los elementos de una tabla o de un índice secundario. De manera predeterminada, una operación `Scan` devuelve todos los atributos de datos de todos los elementos de la tabla o el índice. Puede utilizar el parámetro `ProjectionExpression` para que `Scan` solo devuelva algunos de los atributos, en lugar de todos ellos.

`Scan` siempre devuelve un conjunto de resultados. Si no se encuentran elementos coincidentes, el conjunto de resultados está vacío.

En una sola solicitud `Scan` se puede recuperar un máximo de 1 MB de datos. Si lo desea, DynamoDB puede aplicar una expresión de filtro a estos datos, para reducir los resultados antes de que se devuelvan al usuario.

**Topics**
+ [Expresiones de filtro para el análisis](#Scan.FilterExpression)
+ [Limitación del número de elementos del conjunto de resultados](#Scan.Limit)
+ [Paginación de los resultados](#Scan.Pagination)
+ [Recuento de los elementos en los resultados](#Scan.Count)
+ [Unidades de capacidad que consume el análisis](#Scan.CapacityUnits)
+ [Coherencia de lectura para el análisis](#Scan.ReadConsistency)
+ [Análisis paralelo](#Scan.ParallelScan)

## Expresiones de filtro para el análisis
<a name="Scan.FilterExpression"></a>

Si tiene que refinar más los resultados de `Scan`, si lo desea puede indicar una expresión de filtro. Una *expresión de filtro* determina qué elementos de los resultados de `Scan` se deben devolver al usuario. Todos los demás resultados se descartan.

Una expresión de filtro se aplica después de que la operación `Scan` haya finalizado, pero antes de devolver los resultados. Por consiguiente, `Scan` consume la misma cantidad de capacidad de lectura aunque se especifique una expresión de filtro.

En una operación `Scan` se puede recuperar un máximo de 1 MB de datos. Este límite se aplica antes de evaluar la expresión de filtro.

Con `Scan`, puede especificar cualquier atributo en una expresión de filtro, incluidos los atributos de clave de partición y de clave de ordenación.

La sintaxis de una expresión de filtro es la misma que la de una expresión de condición. Las expresiones de filtro pueden utilizar los comparadores, funciones y operadores lógicos que las expresiones de condición. Consulte [Expresiones, operadores y funciones de condición y filtro en DynamoDB](Expressions.OperatorsAndFunctions.md) para obtener más información sobre operadores lógicos.

**Example**  
En el siguiente ejemplo de la AWS Command Line Interface (AWS CLI) se examina la tabla `Thread` y solo se devuelven los últimos elementos publicados por un usuario determinado.  

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

## Limitación del número de elementos del conjunto de resultados
<a name="Scan.Limit"></a>

La operación `Scan` permite limitar el número de elementos que devuelve en el resultado. Para ello, establezca el parámetro `Limit` en el número máximo de elementos que desea que devuelva la operación `Scan`, antes de la evaluación de la expresión de filtro.

Por ejemplo, suponga que utiliza la operación `Scan` en una tabla con un valor de `Limit` de `6` y sin expresión de filtro. El resultado de `Scan` contiene los seis primeros elementos de la tabla.

Ahora, suponga que agrega una expresión de filtro a `Scan`. En este caso, DynamoDB aplica la expresión de filtro a los seis elementos que se hayan devuelto y descarta los que no coincidan. El resultado de `Scan` final contendrá 6 elementos o menos, según el número de elementos que el filtro elimine.

## Paginación de los resultados
<a name="Scan.Pagination"></a>

DynamoDB *pagina* los resultados de las operaciones `Scan`. La paginación permite dividir los resultados de `Scan` en "páginas" de datos con un tamaño de 1 MB (o menos). Una aplicación puede procesar la primera página de resultados, luego la segunda página, y así sucesivamente.

Una operación `Scan` única devuelve solamente un conjunto de resultados que se ajuste al límite de tamaño de 1 MB. 

Para determinar si hay más resultados y para recuperarlos de página en página, las aplicaciones deben hacer lo siguiente:

1. Examinar el resultado de `Scan` de bajo nivel:
   + Si el resultado contiene una entrada `LastEvaluatedKey`, vaya al paso 2.
   + Si *no* figura `LastEvaluatedKey` en el resultado, no hay más elementos que recuperar.

1. Crear una nueva solicitud `Scan` con los mismos parámetros que la anterior. Sin embargo, esta vez, se toma el valor `LastEvaluatedKey` del paso 1 y se usa como parámetro `ExclusiveStartKey` en la nueva solicitud `Scan`.

1. Ejecutar la nueva solicitud `Scan`.

1. Ir al paso 1.

Es decir, el valor de `LastEvaluatedKey` de la respuesta de `Scan` debe utilizarse como valor de `ExclusiveStartKey` en la siguiente solicitud `Scan`. Si no hay un componente `LastEvaluatedKey` en una respuesta de `Scan`, significa que se ha recuperado la última página de resultados. La ausencia de `LastEvaluatedKey` es la única forma de saber que se ha alcanzado el final del conjunto de resultados.

Puede utilizar la AWS CLI para ver este comportamiento. La AWS CLI envía solicitudes `Scan` de bajo nivel a DynamoDB una y otra vez hasta que `LastEvaluatedKey` ya no esté presente en los resultados. Considere el siguiente ejemplo de la AWS CLI que examina toda la tabla `Movies`, pero solo devuelve las películas de un 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, la AWS CLI se encarga de la paginación automáticamente. No obstante, en este ejemplo, el parámetro AWS CLI de la `--page-size` limita el número de elementos por página. El parámetro `--debug` muestra información de bajo nivel de las solicitudes y las respuestas.

**nota**  
Los resultados de paginación también diferirán en función de los parámetros de entrada que pase.   
El uso de `aws dynamodb scan --table-name Prices --max-items 1` devuelve un `NextToken`
El uso de `aws dynamodb scan --table-name Prices --limit 1` devuelve un `LastEvaluatedKey`.
También tenga en cuenta que usar un `--starting-token` en particular requiere el valor de `NextToken`. 

Si ejecuta el ejemplo, la primera respuesta de DynamoDB será similar a la siguiente.

```
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}'
```

El elemento `LastEvaluatedKey` de la respuesta indica que no se han recuperado todos los elementos. La AWS CLI envía entonces otra solicitud `Scan` a DynamoDB. Este patrón de solicitud y respuesta continúa hasta la respuesta final.

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

La ausencia de `LastEvaluatedKey` indica que no hay más elementos que recuperar.

**nota**  
Los SDK de AWS se encargan también de las respuestas de DynamoDB de bajo nivel (incluida la presencia o ausencia de `LastEvaluatedKey`) y proporcionan varias abstracciones para paginar los resultados de `Scan`. Por ejemplo, la interfaz de documentos de SDK para Java proporciona compatibilidad con `java.util.Iterator` para que pueda examinar los resultados de uno en uno.  
Para ver ejemplos de código en diversos lenguajes de programación, consulte la [Guía de inicio de Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/) y la documentación del SDK de AWS correspondiente a su lenguaje.

## Recuento de los elementos en los resultados
<a name="Scan.Count"></a>

Además de los elementos que coinciden con los criterios, la respuesta de `Scan` contiene las entradas siguientes:
+ `ScannedCount`: El número de elementos evaluados, antes de que se aplique cualquier `ScanFilter`. Un valor de `ScannedCount` elevado, con pocos resultados de `Count` o ninguno indica que la operación `Scan` ha sido ineficiente. Si no ha utilizado un filtro en la solicitud, `ScannedCount` es igual que `Count`. 
+ `Count`: El número de elementos restantes *después* de aplicar una expresión de filtro (si la hay).

**nota**  
Si no se utiliza una expresión de filtro, `ScannedCount` y `Count` tendrán el mismo valor.

Si el tamaño del conjunto de resultados de `Scan` es mayor que 1 MB, entonces `ScannedCount` y `Count` representarán únicamente un recuento parcial de los elementos totales. Deberá llevar a cabo varias operaciones `Scan` para recuperar todos los resultados (consulte [Paginación de los resultados](#Scan.Pagination)).

Cada respuesta de `Scan` contendrá los valores de `ScannedCount` y `Count` de los elementos que se han procesado en esa solicitud `Scan` concreta. Para obtener totales globales para todas las solicitudes `Scan`, puede llevar un recuento total de `ScannedCount` y `Count`.

## Unidades de capacidad que consume el análisis
<a name="Scan.CapacityUnits"></a>

Puede utilizar la operación `Scan` en cualquier tabla o índice secundario. Las operaciones `Scan` consumen las unidades de capacidad de lectura, como se indica a continuación.


****  

| Si `Scan` se aplica a... | DynamoDB consume unidades de capacidad de lectura de... | 
| --- | --- | 
| Tabla | La capacidad de lectura aprovisionada de la tabla. | 
| Índice secundario global | La capacidad de lectura aprovisionada del índice. | 
| Índice secundario local | La capacidad de lectura aprovisionada de la tabla base. | 

**nota**  
Las políticas [basadas en recursos](access-control-resource-based.md) no admiten actualmente el acceso entre cuentas para operaciones de análisis de índices secundarios.

De forma predeterminada, una operación `Scan` no devuelve datos sobre la cantidad de capacidad de lectura que consume. Sin embargo, puede especificar el parámetro `ReturnConsumedCapacity` en una solicitud `Scan` para obtener esta información. A continuación se muestran los ajustes válidos de `ReturnConsumedCapacity`:
+ `NONE`: no se devuelven datos de capacidad consumida. (Esta es la opción predeterminada.)
+ `TOTAL`: la respuesta incluye el número total de unidades de capacidad de lectura consumidas.
+ `INDEXES`: la respuesta muestra el número total de unidades de capacidad de lectura consumidas, así como la capacidad consumida de cada tabla e índice a los que se ha obtenido acceso.

DynamoDB calcula el número de unidades de capacidad de lectura consumidas según el número de elementos y el tamaño de dichos elementos, no según la cantidad de datos que se devuelven a una aplicación. Por este motivo, el número de unidades de capacidad consumidas es el mismo si se solicitan todos los atributos (el comportamiento predeterminado) o solo algunos de ellos (mediante una expresión de proyección). El número también es el mismo tanto si se utiliza una expresión de filtro como si no. `Scan`consume una unidad de capacidad de lectura mínima para realizar una lectura altamente coherente por segundo o dos lecturas coherentes posteriores por segundo para un elemento de hasta 4 KB. Para leer un elemento mayor que 4 KB, DynamoDB necesita unidades de solicitud de lectura adicionales. Con las tablas vacías y las tablas muy grandes con una cantidad escasa de claves de partición, es posible que se cobren algunas RCU adicionales además de la cantidad de datos analizados. Esto cubre el costo de atender la solicitud `Scan`, incluso si no hay datos.

## Coherencia de lectura para el análisis
<a name="Scan.ReadConsistency"></a>

De forma predeterminada, una operación `Scan` lleva a cabo lecturas consistentes finales. Esto significa que los resultados de `Scan` podrían no reflejar los cambios provocados por operaciones `PutItem` o `UpdateItem` realizadas recientemente. Para obtener más información, consulte [Coherencia de lectura de DynamoDB](HowItWorks.ReadConsistency.md).

Si requiere lecturas de consistencia alta desde el momento en que se inicie la operación `Scan`, establezca el parámetro `ConsistentRead` en `true` en la solicitud `Scan`. De este modo, se asegurará de que todas las operaciones de escritura que se han completado antes de iniciar `Scan` se incluyan en la respuesta de `Scan`. 

Establecer `ConsistentRead` en `true` puede resultar útil para realizar backup o replicaciones de tablas, combinado con [DynamoDB Streams](./Streams.html). En primer lugar, se utiliza `Scan` con `ConsistentRead` establecido en true para obtener una copia consistente de los datos de la tabla. Durante la operación `Scan`, DynamoDB Streams registra la actividad de escritura adicional que se produce en la tabla. Una vez que la operación `Scan` ha finalizado, puede aplicar la actividad de escritura de la secuencia a la tabla.

**nota**  
Una operación `Scan` con `ConsistentRead` establecido en `true` consumirá el doble de unidades de capacidad de lectura que si `ConsistentRead` se deja establecido en su valor predeterminado (`false`).

## Análisis paralelo
<a name="Scan.ParallelScan"></a>

De forma predeterminada, la operación `Scan` procesa los datos secuencialmente. Amazon DynamoDB devuelve los datos a la aplicación en incrementos de 1 MB y una aplicación lleva a cabo operaciones `Scan` adicionales para recuperar la siguiente franja de 1 MB de datos. 

Cuanto mayor es la tabla o el índice que se analiza, más tiempo tarda `Scan` en completarse. Además, puede que una operación `Scan` secuencial no consiga siempre utilizar plenamente la capacidad de rendimiento de lectura aprovisionada. Esto se debe a que, aunque DynamoDB distribuye los datos de las tablas grandes entre varias particiones físicas, una operación `Scan` solo puede leer una partición a la vez. Por este motivo, el desempeño de una operación `Scan` se ve restringido por el desempeño máximo de cada partición individual.

Para abordar estos problemas, la operación `Scan` puede dividir una tabla o un índice secundario lógicamente en varios *segmentos*, de tal forma que varios procesos de trabajo de la aplicación puedan examinarlos en paralelo. Cada proceso de trabajo puede ser un subproceso (en los lenguajes de programación que admiten la ejecución de múltiples subprocesos) o un proceso del sistema operativo. Para llevar a cabo un examen en paralelo, cada proceso de trabajo emite su propia solicitud `Scan` con los siguientes parámetros:
+ `Segment` segmento que un proceso de trabajo concreto examinará. Cada proceso de trabajo debe utilizar un valor diferente de `Segment`.
+ `TotalSegments` número total de segmentos del examen en paralelo. Este valor debe ser el mismo que el número de procesos de trabajo que la aplicación va a utilizar.

En el siguiente diagrama se muestra cómo una aplicación de ejecución multiproceso realiza una operación `Scan` en paralelo con tres grados de paralelismo.

![\[Aplicación de varios subprocesos que realiza un análisis paralelo dividiendo una tabla en tres segmentos.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/ParallelScan.png)




En este diagrama, la aplicación crea tres subprocesos y asigna un número a cada uno de ellos. Los segmentos parten de cero, de modo que el primer número siempre es 0. Cada subproceso emite una solicitud `Scan` y establece el valor de `Segment` en el número designado y el valor de `TotalSegments`, en 3. Cada subproceso examina su segmento designado, recupera datos en franjas de 1 MB a la vez y devuelve los datos al subproceso principal de la aplicación.

DynamoDB asigna elementos a los *segmentos* mediante la aplicación de una función hash a la clave de partición de cada elemento. Para un valor de `TotalSegments` determinado, todos los elementos con la misma clave de partición siempre se asignan al mismo `Segment`. Esto significa que en una tabla en la que *elemento 1*, *elemento 2* y *elemento 3* comparten `pk="account#123"` (pero tienen claves de clasificación diferentes), el mismo trabajador procesará estos elementos, independientemente de los valores de las claves de clasificación o del tamaño de la *recopilación de elementos*.

Como la asignación de *segmentos* se basa únicamente en el hash de la clave de partición, los segmentos pueden distribuirse de forma desigual. Es posible que algunos segmentos no contengan elementos, mientras que otros pueden contener muchas claves de partición con grandes recopilaciones de elementos. Como resultado, aumentar el número total de segmentos no garantiza un rendimiento de análisis más rápido, especialmente cuando las claves de partición no están distribuidas uniformemente en el espacio de claves.

Los valores de `Segment` y `TotalSegments` se aplican a las solicitudes `Scan` individuales; puede utilizar valores diferentes en cualquier momento. Es posible que tenga que experimentar con estos valores y con el número de procesos de trabajo utilizados hasta lograr el desempeño óptimo de la aplicación.

**nota**  
Un examen en paralelo con un gran número de procesos de trabajo puede consumir fácilmente todo el rendimiento aprovisionado de la tabla o el índice que se examina. Es preferible evitar este tipo de exámenes si la tabla o el índice también llevan a cabo una intensa actividad de lectura o escritura de otras aplicaciones.  
Para controlar la cantidad de datos devueltos por cada solicitud, utilice el parámetro `Limit`. Esto puede ayudar a evitar situaciones en las que un proceso de trabajo consume todo el desempeño provisionado a costa de todos los demás procesos de trabajo.

# PartiQL: un lenguaje de consulta compatible con SQL para Amazon DynamoDB
<a name="ql-reference"></a>

Compatibilidad con Amazon DynamoDB [PartiQL](https://partiql.org/), un lenguaje de consulta compatible con SQL, para seleccionar, insertar, actualizar y eliminar datos en Amazon DynamoDB. Utilizando PartiQL, puede interactuar fácilmente con tablas de DynamoDB y ejecutar consultas ad hoc utilizando la Consola de administración de AWS, NoSQL Workbench, AWS Command Line Interface y las API de DynamoDB para PartiQL.

Las operaciones PartiQL proporcionan la misma disponibilidad, latencia y rendimiento que las demás operaciones del plano de datos de DynamoDB.

En las siguientes secciones se describe la implementación DynamoDB de PartiQL.

**Topics**
+ [¿Qué es PartiQL?](#ql-reference.what-is)
+ [PartiQL en Amazon DynamoDB](#ql-reference.what-is)
+ [Introducción](ql-gettingstarted.md)
+ [Tipos de datos](ql-reference.data-types.md)
+ [Instrucciones](ql-reference.statements.md)
+ [Funciones](ql-functions.md)
+ [Operadores](ql-operators.md)
+ [Transacciones](ql-reference.multiplestatements.transactions.md)
+ [Operaciones por lotes](ql-reference.multiplestatements.batching.md)
+ [Políticas de IAM](ql-iam.md)

## ¿Qué es PartiQL?
<a name="ql-reference.what-is"></a>

*PartiQL* proporciona acceso a consultas compatible con SQL en múltiples almacenes de datos que contienen datos estructurados, datos semiestructurados y datos anidados. Es ampliamente utilizado en Amazon y ahora está disponible como parte de muchos servicios de AWS, incluido DynamoDB.

Para obtener la especificación PartiQL y un tutorial sobre el lenguaje de consulta principal, consulte la [Documentación de PartiQL](https://partiql.org/docs.html).

**nota**  
Amazon DynamoDB admite *subconjunto* del lenguaje de consulta de [PartiQL](https://partiql.org/).
Amazon DynamoDB no admite el formato de datos [Amazon Ion](http://amzn.github.io/ion-docs/) o literales de Amazon Ion.

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

Para ejecutar consultas PartiQL en DynamoDB, puede utilizar:
+ La consola de DynamoDB
+ Uso de NoSQL Workbench
+ La AWS Command Line Interface (AWS CLI)
+ Las API de DynamoDB

Para obtener información sobre el uso de estos métodos para acceder a DynamoDB, consulte [Acceso a DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html).

# Introducción a PartiQL para DynamoDB
<a name="ql-gettingstarted"></a>

En esta sección se describe cómo utilizar PartiQL para DynamoDB desde la consola de Amazon DynamoDB, la AWS Command Line Interface (AWS CLI) y las API de DynamoDB.

En los ejemplos siguientes, se usa la tabla de DynamoDB que se define en el tutorial [Introducción a DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html) como requisito previo.

Para obtener información sobre cómo usar la consola de DynamoDB, AWS Command Line Interface o las API de DynamoDB para acceder a DynamoDB, consulte [Acceso a DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html).

Para [descargar](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html) y usar el [NoSQL Workbench](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html) para crear instrucciones [PartiQL para DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) elija **PartiQL operations (Operaciones de PartiQL)** en la esquina superior derecha del NoSQL Workbench para DynamoDB [Operation Builder (Creador de operaciones)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.querybuilder.operationbuilder.html).

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

![\[Interfaz de editor PartiQL que muestra el resultado de ejecutar la operación de consulta en la tabla Música.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/partiqlgettingstarted.png)


1. Inicie sesión en la Consola de administración de AWS y abra la consola de DynamoDB en [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. En el panel de navegación del lado izquierdo de la consola, elija **Editor PartiQL**.

1. Elija la tabla **Música**.

1. Ellija **Tabla de consulta**. Esta acción genera una consulta que no dará como resultado un análisis de tabla completo.

1. Reemplazar `partitionKeyValue` con el valor de la cadena `Acme Band`. Reemplazar `sortKeyValue` con el valor de la cadena `Happy Day`.

1. Seleccione el botón **Run** (Ejecutar). 

1. Puede ver los resultados de la consulta seleccionando los botones **Table view (Vista de tabla)** o **JSON view (Vista JSON)**. 

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

![\[Interfaz de NoSQL Workbench. Muestra una instrucción SELECT de PartiQL que puede ejecutar en la tabla Música.\]](http://docs.aws.amazon.com/es_es/amazondynamodb/latest/developerguide/images/workbench/partiql.single.png)


1. Seleccionar **Instrucción PartiQL**.

1. Ingrese la siguiente PartiQL [Instrucción SELECT](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html) 

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

1. Para especificar un valor para los parámetros `Artist` y `SongTitle`:

   1. Elija **Parámetros de solicitudes opcionales**.

   1. Elija **Agregar nuevos parámetros**.

   1. Elija el tipo de atributo **string** y valor `Acme Band`.

   1. Repita los pasos b y c y elija el tipo **string** y valor `PartiQL Rocks`. 

1. Si desea generar código, seleccione **Generate code (Generar código)**.

   Seleccione el idioma que desee en las pestañas mostradas. Ahora puede copiar este código y utilizarlo en su aplicación.

1. Si desea que la operación se ejecute inmediatamente, elija **Ejecutar**.

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

1. Cree un elemento en la tabla `Music` utilizando la instrucción INSERT PartiQL. 

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

1. Recuperar un elemento de la tabla Música mediante la instrucción SELECT PartiQL.

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

1. Actualice un elemento en la tabla `Music` usando la instrucción UPDATE PartiQL.

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

   Agregue un valor de lista para un elemento en la tabla `Music`. 

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

   Quitar un valor de lista para un elemento en la tabla `Music`. 

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

   Agregue un nuevo miembro de mapa para un elemento la tabla `Music`. 

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

   Agregue un nuevo atributo de conjunto de cadenas para un elemento en la tabla `Music`. 

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

   Actualice un atributo de conjunto de cadenas para un elemento en la tabla `Music`. 

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

1. Elimine un elemento de la tabla `Music` mediante la instrucción DELETE PartiQL.

   ```
   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());
        }
    }

}
```

------

## Uso de instrucciones parametrizadas
<a name="ql-gettingstarted.parameterized"></a>

En lugar de incrustar valores directamente en una cadena de instrucciones PartiQL, puede utilizar marcadores de posición con signos de interrogación (`?`) y suministrar los valores de forma independiente en el campo `Parameters`. Cada `?` se sustituye por el valor del parámetro correspondiente, en el orden en que se proporcionan.

El uso de instrucciones parametrizadas es una práctica recomendada porque separa la estructura de las instrucciones de los valores de los datos, lo que facilita su lectura y reutilización. También evita la necesidad de formatear y escapar manualmente de los valores de los atributos de la cadena de la instrucción.

Las instrucciones parametrizadas se admiten en las operaciones `ExecuteStatement`, `BatchExecuteStatement` y `ExecuteTransaction`.

En los siguientes ejemplos, se recupera un elemento de la tabla `Music` mediante valores parametrizados para la clave de partición y la clave de clasificación.

------
#### [ 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**  
El ejemplo de Java de la sección de introducción anterior utiliza en todo momento sentencias parametrizadas. El método `getPartiQLParameters()` crea la lista de parámetros y cada instrucción utiliza marcadores de posición `?` en lugar de valores insertados.

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

En la tabla siguiente se enumeran los tipos de datos que puede usar con PartiQL para DynamoDB.

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

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

La instrucción siguiente muestra cómo insertar los siguientes tipos de datos: `String`, `Number`, `Map`, `List`, `Number Set` y `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'>>
}
```

La siguiente instrucción muestra cómo insertar nuevos elementos en los tipos `Map`, `List`, `Number Set` y `String Set` y cambiar el valor de un 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'
```

La siguiente instrucción muestra cómo eliminar elementos de los tipos `Map`, `List`, `Number Set` y `String Set` y cambiar el valor de un 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 obtener más información, consulte [Tipos de datos de DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes).

# Instrucciones PartiQL para DynamoDB
<a name="ql-reference.statements"></a>

Amazon DynamoDB admite las siguientes instrucciones PartiQL.

**nota**  
DynamoDB no es compatible con todas las instrucciones PartiQL.  
Esta referencia proporciona sintaxis básica y ejemplos de uso de instrucciones PartiQL que se ejecutan manualmente mediante la AWS CLI o API.

*Lenguaje de manipulación de datos*(DML) es el conjunto de instrucciones PartiQL que se utiliza para administrar datos en tablas de DynamoDB. Puede usar instrucciones DML para agregar, modificar o eliminar datos de una tabla.

Se admiten las siguientes instrucciones DML y lenguaje de consulta:
+ [Instrucciones de selección de PartiQL para DynamoDB](ql-reference.select.md)
+ [Instrucciones de actualización de PartiQL para DynamoDB](ql-reference.update.md)
+ [Instrucciones de inserción de PartiQL para DynamoDB](ql-reference.insert.md)
+ [Instrucciones de eliminación de PartiQL para DynamoDB](ql-reference.delete.md)

[Realización de transacciones con PartiQL para DynamoDB](ql-reference.multiplestatements.transactions.md) y [Ejecución de operaciones por lote con PartiQL para DynamoDB](ql-reference.multiplestatements.batching.md) también son compatibles con PartiQL para DynamoDB.

# Instrucciones de selección de PartiQL para DynamoDB
<a name="ql-reference.select"></a>

Se utiliza la instrucción `SELECT` para recuperar datos de una tabla de Amazon DynamoDB.

Si se usa la instrucción `SELECT` se puede generar un análisis completo de la tabla si no se proporciona una condición de igualdad o IN con una clave de partición en la cláusula WHERE. La operación de análisis examina cada elemento para comprobar si presenta los valores solicitados y permite utilizar el rendimiento aprovisionado para una tabla o un índice grandes en una sola operación. 

Si desea evitar el análisis completo de la tabla en PartiQL, puede:
+ Cree su instrucción `SELECT` para que no resulten en análisis completos de la tabla asegurándose de que su [condición de la cláusula WHERE](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html#ql-reference.select.parameters) se configura en consecuencia.
+ Desactive los análisis completos de tablas mediante la política de IAM especificada en [Ejemplo: permitir instrucciones Select y denegar instrucciones de análisis de tabla completa en PartiQL para DynamoDB](ql-iam.md#access-policy-ql-iam-example6), en la guía para desarrolladores de DynamoDB.

Para obtener más información, consulte [Prácticas recomendadas para consultar y examinar datos](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-query-scan.html), en la guía para desarrolladores de DynamoDB.

**Topics**
+ [Sintaxis](#ql-reference.select.syntax)
+ [Parameters](#ql-reference.select.parameters)
+ [Ejemplos](#ql-reference.select.examples)

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

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

## Parameters
<a name="ql-reference.select.parameters"></a>

***expression***  
(Requerido) Una proyección formada a partir del comodín `*` o una lista de proyección de uno o más nombres de atributos o rutas de documentos del conjunto de resultados. Una expresión puede consistir en llamadas a [Uso de funciones de PartiQL con DynamoDB](ql-functions.md) o campos modificados por [Operadores aritméticos, comparativos y lógicos de PartiQL para DynamoDB](ql-operators.md).

***table***  
(Necesario) Nombre de la tabla que se va a consultar.

***Índice de***  
(Opcional) El nombre del índice que se consultará.  
Debe agregar comillas dobles al nombre de la tabla y al nombre del índice al consultar uno.  

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

***condition***  
(Opcional) Criterios de selección para la consulta.  
Para asegurarse de que una instrucción `SELECT` no da como resultado un análisis completo de la tabla, la condición de cláusula `WHERE` debe especificar una clave de partición. Utilice el operador de igualdad o IN.  
Por ejemplo, si tiene una tabla `Orders` con una clave de partición `OrderID`y otros atributos que no son clave, incluido una `Address`, las siguientes instrucciones no resultarían en un análisis completo de la tabla:  

```
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]
```
Las siguientes instrucciones de `SELECT`, sin embargo, resultarán en un análisis completo de la tabla:  

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

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

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

***clave***  
(Opcional) Una clave hash o una clave de ordenación que se va a utilizar para ordenar los resultados devueltos. El orden predeterminado es ascendente (`ASC`) especifique `DESC` si desea que los resultados se vuelvan a ejecutar en orden descendente.

**nota**  
Si omite la cláusula `WHERE`, se recuperarán todos los elementos de la tabla.

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

La siguiente consulta devuelve un elemento, si existe, de la tabla `Orders` especificando la clave de partición, `OrderID` y utilizando el operador de igualdad.

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

La siguiente consulta devuelve todos los elementos de la tabla `Orders` que tiene una clave de partición determinada, `OrderID`, valores utilizando el operador OR.

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

La siguiente consulta devuelve todos los elementos de la tabla `Orders` que tiene una clave de partición determinada, `OrderID`, valores utilizando el operador IN. Los resultados devueltos están en orden descendente, basados en el valor del atributo clave `OrderID`.

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

La siguiente consulta muestra un análisis de tabla completo que devuelve todos los elementos de la tabla `Orders` que tienen un `Total` mayor que 500, donde `Total` es un atributo que no es clave.

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

La siguiente consulta muestra un análisis de tabla completo que devuelve todos los elementos de la tabla `Orders` con un rango de orden `Total`, utilizando el operador IN y un atributo que no es clave `Total`.

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

La siguiente consulta muestra un análisis de tabla completo que devuelve todos los elementos de la tabla `Orders` dentro de un rango de orden `Total` específico, utilizando el operador BETWEEN y un atributo que no es clave `Total`.

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

La siguiente consulta devuelve la primera fecha en que se utilizó un dispositivo firestick para ver especificando la clave de partición `CustomerID` y la clave de ordenación `MovieID` en la condición de cláusula WHERE y utilizando rutas de documento en la cláusula SELECT.

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

La siguiente consulta muestra un análisis de tabla completo que devuelve la lista de elementos en los que un dispositivo de firestick se utilizó por primera vez después del 24/12/19 mediante rutas de documento en la condición de cláusula WHERE.

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

# Instrucciones de actualización de PartiQL para DynamoDB
<a name="ql-reference.update"></a>

Use la instrucción `UPDATE` para modificar el valor de uno o más atributos dentro de un elemento de una tabla de Amazon DynamoDB. 

**nota**  
Sólo puede actualizar un elemento a la vez; no puede emitir una sola instrucción de DynamoDB PartiQL que actualice varios elementos. Para obtener información sobre cómo actualizar varios elementos, consulte [Realización de transacciones con PartiQL para DynamoDB](ql-reference.multiplestatements.transactions.md) or [Ejecución de operaciones por lote con PartiQL para DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [Sintaxis](#ql-reference.update.syntax)
+ [Parameters](#ql-reference.update.parameters)
+ [Valor devuelto](#ql-reference.update.return)
+ [Ejemplos](#ql-reference.update.examples)

## Sintaxis
<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] *
```

## Parameters
<a name="ql-reference.update.parameters"></a>

***table***  
(Necesario) Tabla que contiene los datos que se van a modificar.

***path***  
(Necesario) Nombre de atributo o ruta de documento que se va a crear o modificar.

***data***  
(Necesario) Valor de atributo o resultado de una operación.  
Las operaciones admitidas para usar con SET:  
+ LIST\$1APPEND: agrega un valor a un tipo de lista.
+ SET\$1ADD: agrega un valor a un número o conjunto de cadenas.
+ SET\$1DELETE: elimina un valor de un número o conjunto de cadenas.

***condition***  
(Necesario) Criterios de selección para el elemento que se va a modificar. Esta condición debe resolverse con un único valor de clave principal.

***returnvalues***  
(Opcional) Utilizar `returnvalues` si desea obtener los atributos del elemento tal como aparecen antes o después de que se actualicen. Los valores válidos son:   
+ `ALL OLD *`: devuelve todos los atributos del elemento, tal y como aparecían antes de la operación de actualización.
+ `MODIFIED OLD *`: devuelve sólo los atributos actualizados, tal y como aparecían antes de la operación de actualización.
+ `ALL NEW *`: devuelve todos los atributos del elemento, tal como aparecen después de la operación de actualización.
+ `MODIFIED NEW *`: devuelve solamente los atributos actualizados, tal y como aparecen después de la operación `UpdateItem`.

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

Esta instrucción no devuelve un valor a menos que se especifique el parámetro `returnvalues`.

**nota**  
Si la cláusula WHERE de la instrucción UPDATE no se evalúa como true (verdadero) para ningún elemento de la tabla DynamoDB, se devuelve `ConditionalCheckFailedException`.

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

Actualiza el valor del atributo de un elemento existente en. Si el atributo no existe, se crea.

En la siguiente consulta se actualiza un elemento de la tabla `"Music"` agregando un atributo de tipo number (`AwardsWon`) y un atributo de tipo map (`AwardDetail`).

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

Puede agregar `RETURNING ALL OLD *` para devolver los atributos tal y como aparecían antes de la operación `Update`.

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

Devuelve lo siguiente:

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

Puede agregar `RETURNING ALL NEW *` para devolver los atributos tal y como aparecían después de la operación `Update`.

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

Devuelve lo siguiente:

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

En la siguiente consulta se actualiza un elemento de la tabla `"Music"` agregando a una lista `AwardDetail.Grammys`.

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

En la siguiente consulta se actualiza un elemento de la tabla `"Music"` eliminando de una lista `AwardDetail.Grammys`.

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

En la siguiente consulta se actualiza un elemento de la tabla `"Music"` agregando `BillBoard`al mapa`AwardDetail`.

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

En la siguiente consulta se actualiza un elemento de la tabla `"Music"` agregando el atributo de conjunto de string `BandMembers`.

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

En la siguiente consulta se actualiza un elemento de la tabla `"Music"` agregando `newbandmember` al conjunto de string `BandMembers`.

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

# Instrucciones de eliminación de PartiQL para DynamoDB
<a name="ql-reference.delete"></a>

Usar la instrucción `DELETE` para eliminar un elemento existente de la tabla de Amazon DynamoDB.

**nota**  
Solo puede eliminar de a un elemento a la vez. No puede emitir una sola instrucción de DynamoDB PartiQL que elimine varios elementos. Para obtener información sobre cómo eliminar varios elementos, consulte [Realización de transacciones con PartiQL para DynamoDB](ql-reference.multiplestatements.transactions.md) or [Ejecución de operaciones por lote con PartiQL para DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [Sintaxis](#ql-reference.delete.syntax)
+ [Parameters](#ql-reference.delete.parameters)
+ [Valor devuelto](#ql-reference.delete.return)
+ [Ejemplos](#ql-reference.delete.examples)

## Sintaxis
<a name="ql-reference.delete.syntax"></a>

```
DELETE FROM table 
 WHERE condition [RETURNING returnvalues]
 <returnvalues>  ::= ALL OLD *
```

## Parameters
<a name="ql-reference.delete.parameters"></a>

***table***  
(Necesario) Tabla de DynamoDB que contiene el elemento que se va a eliminar.

***condition***  
(Necesario) Criterios de selección para el elemento que se va a eliminar; esta condición debe resolverse en un único valor de clave principal.

***returnvalues***  
(Opcional) Utilizar `returnvalues` si desea obtener los atributos del elemento tal y como aparecían antes de eliminarlos. Los valores válidos son:   
+ `ALL OLD *`: se devuelve el contenido del elemento anterior.

## Valor devuelto
<a name="ql-reference.delete.return"></a>

Esta instrucción no devuelve un valor a menos que se especifique el parámetro `returnvalues`.

**nota**  
Si la tabla de DynamoDB no tiene ningún elemento con la misma clave principal que la del elemento para el que se emite DELETE, se devuelve SUCCESS con 0 elementos eliminados. Si la tabla tiene un elemento con la misma clave principal, pero la condición de la cláusula WHERE de la instrucción DELETE se evalúa como false (falso), se devuelve `ConditionalCheckFailedException`.

## Ejemplos
<a name="ql-reference.delete.examples"></a>

La siguiente consulta elimina un elemento de la tabla `"Music"`.

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks'
```

Puede agregar el parámetro `RETURNING ALL OLD *` para devolver los datos eliminados.

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks' RETURNING ALL OLD *
```

La instrucción `Delete` devuelve ahora lo siguiente:

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

# Instrucciones de inserción de PartiQL para DynamoDB
<a name="ql-reference.insert"></a>

Usar la instrucción `INSERT` para agregar un elemento a una tabla de Amazon DynamoDB.

**nota**  
Sólo puede insertar un elemento a la vez; no puede emitir una sola instrucción de DynamoDB PartiQL que inserte varios elementos. Para obtener información sobre cómo insertar varios elementos, consulte [Realización de transacciones con PartiQL para DynamoDB](ql-reference.multiplestatements.transactions.md) or [Ejecución de operaciones por lote con PartiQL para DynamoDB](ql-reference.multiplestatements.batching.md).

**Topics**
+ [Sintaxis](#ql-reference.insert.syntax)
+ [Parameters](#ql-reference.insert.parameters)
+ [Valor devuelto](#ql-reference.insert.return)
+ [Ejemplos](#ql-reference.insert.examples)

## Sintaxis
<a name="ql-reference.insert.syntax"></a>

Inserte un único elemento.

```
INSERT INTO table VALUE item
```

## Parameters
<a name="ql-reference.insert.parameters"></a>

***table***  
(Necesario) La tabla en la que desea insertar los datos. La tabla debe existir previamente.

***elemento***  
(Necesario) Un elemento válido de DynamoDB representado como [tupla PartiQL](https://partiql.org/docs.html). Debe especificar *un solo* elemento y cada nombre de atributo en el elemento distingue entre mayúsculas y minúsculas y se puede denotar con comillas *simples* (`'...'`) en PartiQL.  
Los valores string también se denotan con comillas *simples* (`'...'`) en PartiQL.

## Valor devuelto
<a name="ql-reference.insert.return"></a>

Esta instrucción no devuelve ningún valor.

**nota**  
Si la tabla DynamoDB ya tiene un elemento con la misma clave principal que la clave principal del elemento que se va a insertar, se devuelve `DuplicateItemException`.

## Ejemplos
<a name="ql-reference.insert.examples"></a>

```
INSERT INTO "Music" value {'Artist' : 'Acme Band','SongTitle' : 'PartiQL Rocks'}
```

# Uso de funciones de PartiQL con DynamoDB
<a name="ql-functions"></a>

PartiQL en Amazon DynamoDB admite las siguientes variantes integradas de funciones estándar de SQL.

**nota**  
DynamoDB no admite actualmente ninguna función SQL que no se incluya en esta lista.

## Funciones de agregación
<a name="ql-functions.aggregate"></a>
+ [Uso de la función SIZE con PartiQL para Amazon DynamoDB](ql-functions.size.md)

## Funciones condicionales
<a name="ql-functions.conditional"></a>
+ [Uso de la función EXISTS con PartiQL para DynamoDB](ql-functions.exists.md)
+ [Uso de la función ATTRIBUTE\$1TYPE con PartiQL para DynamoDB](ql-functions.attribute_type.md)
+ [Uso de la función BEGINS\$1WITH con PartiQL para DynamoDB](ql-functions.beginswith.md)
+ [Uso de la función CONTAINS con PartiQL para DynamoDB](ql-functions.contains.md)
+ [Uso de la función MISSING con PartiQL para DynamoDB](ql-functions.missing.md)

# Uso de la función EXISTS con PartiQL para DynamoDB
<a name="ql-functions.exists"></a>

Puede usar EXISTS para realizar la misma función que`ConditionCheck` hace en la API [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems). La función EXISTS sólo se puede utilizar en transacciones.

Dado un valor, devuelve `TRUE` si el valor es una colección no vacía. De lo contrario, devuelve `FALSE`.

**nota**  
Esta función sólo se puede utilizar en operaciones transaccionales.

## Sintaxis
<a name="ql-functions.exists.syntax"></a>

```
EXISTS ( statement )
```

## Argumentos
<a name="ql-functions.exists.arguments"></a>

*statement *  
(Requerido) La instrucción SELECT que la función evalúa.  
La instrucción SELECT debe especificar una clave principal completa y otra condición.

## Tipo de retorno
<a name="ql-functions.exists.return-type"></a>

`bool`

## Ejemplos
<a name="ql-functions.exists.examples"></a>

```
EXISTS(
    SELECT * FROM "Music" 
    WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks')
```

# Uso de la función BEGINS\$1WITH con PartiQL para DynamoDB
<a name="ql-functions.beginswith"></a>

Devuelve `TRUE` si el atributo especificado comienza por una subcadena determinada.

## Sintaxis
<a name="ql-functions.beginswith.syntax"></a>

```
begins_with(path, value )
```

## Argumentos
<a name="ql-functions.beginswith.arguments"></a>

*path*  
(Necesario) Nombre del atributo o ruta del documento que se va a utilizar.

*value*  
(Necesario) La cadena que se va a buscar.

## Tipo de retorno
<a name="ql-functions.beginswith.return-type"></a>

`bool`

## Ejemplos
<a name="ql-functions.beginswith.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND begins_with("Address", '7834 24th')
```

# Uso de la función MISSING con PartiQL para DynamoDB
<a name="ql-functions.missing"></a>

Devuelve `TRUE` si el elemento no contiene el atributo especificado. Sólo los operadores de igualdad y desigualdad pueden ser utilizados con esta función.

## Sintaxis
<a name="ql-functions.missing.syntax"></a>

```
 attributename IS | IS NOT  MISSING 
```

## Argumentos
<a name="ql-functions.missing.arguments"></a>

*attributename*  
(Necesario) Nombre del atributo que se va a buscar.

## Tipo de retorno
<a name="ql-functions.missing.return-type"></a>

`bool`

## Ejemplos
<a name="ql-functions.missing.examples"></a>

```
SELECT * FROM Music WHERE "Awards" is MISSING
```

# Uso de la función ATTRIBUTE\$1TYPE con PartiQL para DynamoDB
<a name="ql-functions.attribute_type"></a>

Devuelve `TRUE` si el atributo de la ruta especificada es de un tipo de datos determinado.

## Sintaxis
<a name="ql-functions.attribute_type.syntax"></a>

```
attribute_type( attributename, type )
```

## Argumentos
<a name="ql-functions.attribute_type.arguments"></a>

*attributename*  
(Necesario) Nombre del atributo que se va a utilizar.

*type*  
(Necesario) Tipo de atributo que se va a comprobar. Para obtener una lista de valores válidos, consulte [attribute\$1type](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) de DynamoDB.

## Tipo de retorno
<a name="ql-functions.attribute_type.return-type"></a>

`bool`

## Ejemplos
<a name="ql-functions.attribute_type.examples"></a>

```
SELECT * FROM "Music" WHERE attribute_type("Artist", 'S')
```

# Uso de la función CONTAINS con PartiQL para DynamoDB
<a name="ql-functions.contains"></a>

Devuelve `TRUE` si el atributo especificado por la ruta es uno de los siguientes:
+ Un valor de tipo String que contiene una determinada subcadena. 
+ Un valor de tipo Set que contiene una entrada determinada perteneciente al conjunto.

Para obtener más información, consulte la función [contains (contiene)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) de DynamoDB. 

## Sintaxis
<a name="ql-functions.contains.syntax"></a>

```
contains( path, substring )
```

## Argumentos
<a name="ql-functions.contains.arguments"></a>

*path*  
(Necesario) Nombre del atributo o ruta del documento que se va a utilizar.

*subcadena*  
(Necesario) La subcadena de atributo o miembro de conjunto que se va a comprobar. Para obtener más información, consulte la función [contains (contiene)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) de DynamoDB.

## Tipo de retorno
<a name="ql-functions.contains.return-type"></a>

`bool`

## Ejemplos
<a name="ql-functions.contains.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND contains("Address", 'Kirkland')
```

# Uso de la función SIZE con PartiQL para Amazon DynamoDB
<a name="ql-functions.size"></a>

Devuelve un número que representa el tamaño de un atributo en bytes. A continuación se muestran los tipos de datos válidos para usarlos con size. Para obtener más información, consulte la función [size (dimensión)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) de DynamoDB.

## Sintaxis
<a name="ql-functions.size.syntax"></a>

```
size( path)
```

## Argumentos
<a name="ql-functions.size.arguments"></a>

*path*  
(Necesario) Nombre del atributo o ruta del documento.   
Para conocer los tipos admitidos, consulte la función [size (dimensión)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) de DynamoDB.

## Tipo de retorno
<a name="ql-functions.size.return-type"></a>

`int`

## Ejemplos
<a name="ql-functions.size.examples"></a>

```
 SELECT * FROM "Orders" WHERE "OrderID"=1 AND size("Image") >300
```

# Operadores aritméticos, comparativos y lógicos de PartiQL para DynamoDB
<a name="ql-operators"></a>

PartiQL en Amazon DynamoDB admite los siguiente [Operadores estándares de SQL](https://www.w3schools.com/sql/sql_operators.asp).

**nota**  
DynamoDB no admite ningún operador SQL que no se incluya en esta lista.

## Operadores aritméticos
<a name="ql-operators.arithmetic"></a>


****  

| Operador | Descripción | 
| --- | --- | 
| \$1 | Add (Suma) | 
| - | Subtract (Sustracción) | 

## Operadores de comparación
<a name="ql-operators.comparison"></a>


****  

| Operador | Descripción | 
| --- | --- | 
| = | Igual que | 
| <> | No igual que | 
| \$1= | No igual que | 
| > | Mayor que | 
| < | Menor que | 
| >= | Mayor o igual que | 
| <= | Menor o igual que | 

## Operadores lógicos
<a name="ql-operators.logical"></a>


****  

| Operador | Descripción | 
| --- | --- | 
| AND | TRUE si todas las condiciones separadas por AND son TRUE | 
| BETWEEN |  `TRUE` si el operando está en el rango de las comparaciones Este operador incluye los límites inferior y superior de los operandos a los que se aplica.  | 
| IN | `TRUE` si el operando es igual a uno de una lista de expresiones (con un máximo de 50 valores de atributo hash o un máximo de 100 valores de atributo no clave). Los resultados se devuelven en páginas de hasta 10 elementos. Si la lista `IN` contiene más valores, debe utilizar los valores `NextToken` devueltos en la respuesta para recuperar las páginas siguientes. | 
| IS | TRUE si el operando es un tipo de datos PartiQL dado, incluyendo NULL o MISSING | 
| NOT | Invierte el valor de una expresión booleana dada | 
| OR | TRUE si alguna de las condiciones está separada por OR son TRUE | 

Consulte [Realización de comparaciones](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Comparators) y [Evaluaciones lógicas](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.LogicalEvaluations) para obtener más información sobre operadores lógicos.

# Realización de transacciones con PartiQL para DynamoDB
<a name="ql-reference.multiplestatements.transactions"></a>

En esta sección se describe cómo utilizar transacciones con PartiQL para DynamoDB. Las transacciones PartiQL están limitadas a un total de 100 instrucciones (acciones).

Para obtener más información acerca de las transacciones de DynamoDB, consulte [Administración de flujos de trabajo complejos con transacciones de DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html).

**nota**  
Toda la transacción debe constar de instrucciones de lectura o de escritura. No puede mezclar ambos en una sola transacción. La función EXISTS es una excepción. Se puede utilizar para verificar la condición de atributos específicos del elemento de una manera similar a `ConditionCheck` en la operación de la API [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems).

**Topics**
+ [Sintaxis](#ql-reference.multiplestatements.transactions.syntax)
+ [Parameters](#ql-reference.multiplestatements.transactions.parameters)
+ [Valores devueltos](#ql-reference.multiplestatements.transactions.return)
+ [Ejemplos](#ql-reference.multiplestatements.transactions.examples)

## Sintaxis
<a name="ql-reference.multiplestatements.transactions.syntax"></a>

```
[
   {
      "Statement":" statement ",
      "Parameters":[
         {
            " parametertype " : " parametervalue "
         }, ...]
   } , ...
]
```

## Parameters
<a name="ql-reference.multiplestatements.transactions.parameters"></a>

***statement***  
(Necesario) Una instrucción compatible con PartiQL para DynamoDB.  
Toda la transacción debe constar de instrucciones de lectura o de escritura. No puede mezclar ambos en una sola transacción.

***parametertype***  
(Opcional) Tipo DynamoDB, si se utilizaron parámetros al especificar la instrucción PartiQL.

***parametervalue***  
(Opcional) Valor de parámetro si se utilizaron parámetros al especificar la instrucción PartiQL.

## Valores devueltos
<a name="ql-reference.multiplestatements.transactions.return"></a>

Esta instrucción no devuelve ningún valor para las operaciones de escritura (INSERT, UPDATE o DELETE). Sin embargo, devuelve valores diferentes para las operaciones de lectura (SELECT) en función de las condiciones especificadas en la cláusula WHERE.

**nota**  
Si alguna de las operaciones singleton INSERT, UPDATE o DELETE devuelve un error, las transacciones se cancelan con la excepción `TransactionCanceledException`, y el código de motivo de cancelación incluye los errores de las operaciones singleton individuales.

## Ejemplos
<a name="ql-reference.multiplestatements.transactions.examples"></a>

En el ejemplo siguiente, se ejecutan varias instrucciones como transacción.

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

1. Guarde el siguiente código JSON en un archivo llamado 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. Ejecute el comando siguiente en un símbolo del sistema.

   ```
   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());
        }
    }

}
```

------

En el ejemplo siguiente se muestran los distintos valores de retorno cuando DynamoDB lee elementos con condiciones diferentes especificadas en la cláusula WHERE.

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

1. Guarde el siguiente código JSON en un archivo llamado 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.  Ejecute el comando siguiente en un símbolo del sistema.

   ```
   aws dynamodb execute-transaction --transact-statements  file://partiql.json
   ```

1. Se devuelve la siguiente respuesta:

   ```
   {
       "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
           {}
       ]
   }
   ```

------

# Ejecución de operaciones por lote con PartiQL para DynamoDB
<a name="ql-reference.multiplestatements.batching"></a>

En esta sección se describe cómo utilizar instrucciones por lote con PartiQL para DynamoDB.

**nota**  
Todo el lote debe constar de instrucciones de lectura o de escritura; no se pueden mezclar ambas en un solo lote.
`BatchExecuteStatement` y `BatchWriteItem` no pueden realizar más de 25 instrucciones por lote.
`BatchExecuteStatement` hace uso de `BatchGetItem` que toma una lista de claves principales en instrucciones independientes.

**Topics**
+ [Sintaxis](#ql-reference.multiplestatements.batching.syntax)
+ [Parameters](#ql-reference.multiplestatements.batching.parameters)
+ [Ejemplos](#ql-reference.multiplestatements.batching.examples)

## Sintaxis
<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 "
         }, ...]
   } , ...
]
```

## Parameters
<a name="ql-reference.multiplestatements.batching.parameters"></a>

***statement***  
(Necesario) Una instrucción compatible con PartiQL para DynamoDB.  
+ Todo el lote debe constar de instrucciones de lectura o de escritura; no se pueden mezclar ambas en un solo lote.
+ `BatchExecuteStatement` y `BatchWriteItem` no pueden realizar más de 25 instrucciones por lote.

***parametertype***  
(Opcional) Tipo DynamoDB, si se utilizaron parámetros al especificar la instrucción PartiQL.

***parametervalue***  
(Opcional) Valor de parámetro si se utilizaron parámetros al especificar la instrucción PartiQL.

## Ejemplos
<a name="ql-reference.multiplestatements.batching.examples"></a>

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

1. Guarde el siguiente json en un archivo llamado 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. Ejecute el comando siguiente en un símbolo del sistema.

   ```
   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 seguridad de IAM con PartiQL para DynamoDB
<a name="ql-iam"></a>

Los siguientes permisos son necesarios:
+ Para leer elementos que utilizan PartiQL para DynamoDB, debe tener el permiso `dynamodb:PartiQLSelect` en la tabla o índice.
+ Para insertar elementos utilizando PartiQL para DynamoDB, debe tener el permiso `dynamodb:PartiQLInsert` en la tabla o índice.
+ Para actualizar elementos con PartiQL para DynamoDB, debe tener el permiso `dynamodb:PartiQLUpdate` en la tabla o índice.
+ Para eliminar elementos que utilizan PartiQL para DynamoDB, debe tener el permiso `dynamodb:PartiQLDelete` en la tabla o índice.

## Ejemplo: Permitir todas las instrucciones PartiQL para DynamoDB (Select/Insert/Update/Delete) en una tabla
<a name="access-policy-ql-iam-example1"></a>

La siguiente política de IAM concede permisos para ejecutar todas las instrucciones PartiQL para DynamoDB en una tabla. 

------
#### [ 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"
         ]
      }
   ]
}
```

------

## Ejemplo: Permitir que PartiQL para DynamoDB seleccione las instrucciones en una tabla
<a name="access-policy-ql-iam-example2"></a>

La siguiente política de IAM concede permisos para ejecutar la instrucción `select`sobre una tabla específica.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## Ejemplo: Permitir instrucciones de inserción de PartiQL para DynamoDB en un índice
<a name="access-policy-ql-iam-example3"></a>

La siguiente política de IAM concede permisos para ejecutar la instrucción `insert` en un í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"
         ]
      }
   ]
}
```

------

## Ejemplo: Permitir las instrucciones transaccionales de PartiQL para DynamoDB sólo en una tabla
<a name="access-policy-ql-iam-example4"></a>

La siguiente política de IAM concede permisos para ejecutar solamente instrucciones transaccionales en una tabla determinada. 

------
#### [ 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"
               ]
            }
         }
      }
   ]
}
```

------

## Ejemplo: Permitir lecturas y escrituras no transaccionales de PartiQL para DynamoDB y bloquear lecturas y escrituras transaccionales de PartiQL en una tabla.
<a name="access-policy-ql-iam-example5"></a>

 La siguiente directiva de IAM otorga permisos para ejecutar lecturas y escrituras no transaccionales de PartiQL para DynamoDB a la vez que bloquea lecturas y escrituras transaccionales de 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"
         ]
      }
   ]
}
```

------

## Ejemplo: permitir instrucciones Select y denegar instrucciones de análisis de tabla completa en PartiQL para DynamoDB
<a name="access-policy-ql-iam-example6"></a>

La siguiente política de IAM concede permisos para ejecutar la instrucción `select` en una tabla específica mientras se bloquean las instrucciones `select` que dan como resultado un examen completo de toda la tabla.

------
#### [ 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"
         ]
      }
   ]
}
```

------

# Uso de elementos: Java
<a name="JavaDocumentAPIItemCRUD"></a>

Puede usar la API de documentos del AWS SDK para Java para realizar operaciones típicas de creación, lectura, actualización y eliminación (CRUD, por sus siglas en inglés) en los elementos de una tabla de Amazon DynamoDB.

**nota**  
Además, SDK para Java proporciona un modelo de persistencia de objetos, que le permite mapear las clases del lado del cliente a las tablas de DynamoDB. Este enfoque puede reducir la cantidad de código que hay que escribir. Para obtener más información, consulte [Java 1.x: DynamoDBMapper](DynamoDBMapper.md).

Esta sección contiene ejemplos de Java que permiten realizar diversas acciones con elementos de la API de documentos de Java y varios ejemplos de trabajo completos.

**Topics**
+ [Colocación de un elemento](#PutDocumentAPIJava)
+ [Obtención de un elemento](#JavaDocumentAPIGetItem)
+ [Escritura por lotes: colocación y eliminación de varios elementos](#BatchWriteDocumentAPIJava)
+ [Obtención por lotes: obtención de varios elementos](#JavaDocumentAPIBatchGetItem)
+ [Actualización de un elemento](#JavaDocumentAPIItemUpdate)
+ [Eliminación de un elemento](#DeleteMidLevelJava)
+ [Ejemplo: operaciones CRUD mediante la API de documentos de AWS SDK para Java](JavaDocumentAPICRUDExample.md)
+ [Ejemplo: operaciones por lotes mediante la API de documentos de AWS SDK para Java](batch-operation-document-api-java.md)
+ [Ejemplo: control de atributos de tipo binario mediante la API de documentos de AWS SDK para Java](JavaDocumentAPIBinaryTypeExample.md)

## Colocación de un elemento
<a name="PutDocumentAPIJava"></a>

El método `putItem` almacena un elemento en una tabla. Si el elemento existe, sustituye el elemento completo. En lugar de ello, si prefiere actualizar solamente algunos atributos concretos, puede usar el método `updateItem`. Para obtener más información, consulte [Actualización de un elemento](#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 estos pasos: 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `Table` para representar la tabla que desea usar.

1. Cree una instancia de la clase `Item` para representar el nuevo elemento. Debe especificar la clave principal del nuevo elemento y sus atributos.

1. Llame al método `putItem` del objeto `Table` utilizando el `Item` que creó en el paso anterior.

En el siguiente ejemplo de código Java se muestran las tareas anteriores. El código escribe un nuevo elemento en la tabla `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);
```

En el ejemplo anterior, el elemento tiene atributos que son escalares (`String`, `Number`, `Boolean`, `Null`), conjuntos (`String Set`) y tipos de documentos (`List`, `Map`).

------

### Especificación de parámetros opcionales
<a name="PutItemJavaDocumentAPIOptions"></a>

Junto con los parámetros requeridos, puede especificar también otros opcionales en el método `putItem`. Por ejemplo, en el ejemplo de código Java siguiente se utiliza un parámetro opcional que permite especificar una condición para cargar el elemento. Si la condición especificada no se cumple, AWS SDK para Java genera una excepción `ConditionalCheckFailedException`. En el ejemplo de código se especifican los parámetros opcionales siguientes en el método `putItem`:
+ Una expresión `ConditionExpression` que define las condiciones de la solicitud. El código define la condición siguiente: si el elemento existente tiene la misma clave principal, solo se sustituirá si tiene también un atributo ISBN igual a un valor específico. 
+ Un mapa de `ExpressionAttributeValues` que se usa en la condición. En este caso, solo se requiere una sustitución: el marcador de posición `:val` de la expresión de condición se sustituye en el tiempo de ejecución por el valor de ISBN real que se va a comprobar.

En el siguiente ejemplo se agrega un nuevo elemento de libro utilizando estos parámetros opcionales.

**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 y documentos JSON
<a name="PutItemJavaDocumentAPI.JSON"></a>

Puede almacenar un documento JSON como atributo en una tabla de DynamoDB. Para ello, se utiliza el método `withJSON` de `Item`. Este método analiza el documento JSON y mapea cada componente a un tipo de datos nativo de DynamoDB.

Suponga que desea almacenar el siguiente documento JSON, que contiene los proveedores que pueden servir pedidos de un producto determinado.

**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"
        ]
    }
}
```

Puede utilizar el método `withJSON` para almacenar esta información en la tabla `ProductCatalog` en un atributo de tipo `Map` denominado `VendorInfo`. En el siguiente ejemplo de código Java se muestra cómo hacerlo.

```
// 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);
```

## Obtención de un elemento
<a name="JavaDocumentAPIGetItem"></a>

Para recuperar un solo elemento, utilice el método `getItem` de un objeto `Table`. Siga estos pasos: 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `Table` para representar la tabla que desea usar.

1. Llame al método `getItem` de la instancia de `Table`. Es preciso especificar la clave principal del elemento que se desea recuperar.

En el siguiente ejemplo de código Java se muestran los pasos anteriores. El código obtiene el elemento que tiene la clave de partición especificada.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Item item = table.getItem("Id", 210);
```

### Especificación de parámetros opcionales
<a name="GetItemJavaDocumentAPIOptions"></a>

Junto con los parámetros requeridos, puede especificar también otros opcionales del método `getItem`. Por ejemplo, en el siguiente ejemplo de código Java se utiliza un método opcional para recuperar solo una lista concreta de atributos y especificar lecturas de consistencia alta. Para obtener más información sobre la consistencia de lectura, consulte . [Coherencia de lectura de DynamoDB](HowItWorks.ReadConsistency.md).)

Puede usar una expresión `ProjectionExpression` para recuperar solamente algunos atributos o componentes concretos, en lugar de un elemento completo. Una expresión `ProjectionExpression` permite especificar atributos de nivel superior o anidados mediante rutas de documentos. Para obtener más información, consulte [Uso de expresiones de proyección en DynamoDB](Expressions.ProjectionExpressions.md).

Los parámetros del método `getItem` no permiten especificar la consistencia de .lectura Sin embargo, puede crear una especificación `GetItemSpec`, que proporciona acceso pleno a toda la información de entrada de la operación de bajo nivel `GetItem`. En el ejemplo de código siguiente se crea una especificación `GetItemSpec` y se utiliza como información de entrada para el 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 un `Item` en formato fácil de leer, utilice el método `toJSONPretty`. El resultado del ejemplo anterior tiene este aspecto.

```
{
  "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 y documentos JSON
<a name="GetItemJavaDocumentAPI.JSON"></a>

En la sección [PutItem y documentos JSON](#PutItemJavaDocumentAPI.JSON), almacena un documento JSON en un atributo `Map` denominado `VendorInfo`. Puede utilizar el método `getItem` para recuperar todo el documento en formato JSON. O puede usar la notación de ruta de documento para recuperar solo algunos de los componentes de ese documento. En el siguiente ejemplo de código Java se muestran estas 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());
```

El resultado del ejemplo anterior tiene este aspecto.

```
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**  
Puede usar el método `toJSON` para convertir cualquier elemento (o sus atributos) en una cadena con formato JSON. En el siguiente ejemplo de código se recuperan varios atributos de nivel superior y anidados y se imprimen los 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());
```
El resultado es similar al siguiente.  

```
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}
```

## Escritura por lotes: colocación y eliminación de varios elementos
<a name="BatchWriteDocumentAPIJava"></a>

La *escritura por lotes* se refiere a colocar y eliminar varios elementos en un lote. El método `batchWriteItem` permite colocar y eliminar varios elementos de una o varias tablas con una sola llamada. A continuación se indican los pasos para colocar o eliminar varios elementos mediante la API de documentos del AWS SDK para Java.

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `TableWriteItems` que describe todas las operaciones de colocación y eliminación de una tabla. Si desea escribir en varias tablas en una misma operación de escritura por lotes, debe crear una instancia de `TableWriteItems` por cada tabla.

1. Llame al método `batchWriteItem` proporcionando los objetos `TableWriteItems` que creó en el paso anterior. 

1. Procese la respuesta. Debe comprobar si en la respuesta se ha devuelto algún elemento de solicitud sin procesar. Esto puede ocurrir si se alcanza la cuota de rendimiento aprovisionado o se produce algún otro error transitorio. Además, DynamoDB limita el tamaño de la solicitud y el número de operaciones que se pueden especificar en ella. Si supera estos límites, DynamoDB rechaza la solicitud. Para obtener más información, consulte [Cuotas en Amazon DynamoDB](ServiceQuotas.md). 

En el siguiente ejemplo de código Java se muestran los pasos anteriores. El ejemplo lleva a cabo una operación `batchWriteItem` en dos tablas: `Forum` y `Thread`. Los objetos `TableWriteItems` correspondientes definen las siguientes acciones:
+ Colocar un elemento en la tabla `Forum`.
+ Colocar y eliminar un elemento en la tabla `Thread`.

A continuación, el código llama a `batchWriteItem` para llevar a cabo la operación.

```
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 ver un ejemplo práctico, consulte [Ejemplo: operación de escritura por lotes mediante la API de documentos de AWS SDK para Java](batch-operation-document-api-java.md#JavaDocumentAPIBatchWrite). 

## Obtención por lotes: obtención de varios elementos
<a name="JavaDocumentAPIBatchGetItem"></a>

El método `batchGetItem` permite recuperar varios elementos de una o varias tablas. Para recuperar un solo elemento, puede usar el método `getItem`. 

Siga estos pasos: 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `TableKeysAndAttributes` que describe una lista de valores de clave principal que se van a recuperar de una tabla. Si desea leer de varias tablas en una misma operación de obtención por lotes, debe crear una instancia de `TableKeysAndAttributes` por cada tabla.

1. Llame al método `batchGetItem` proporcionando los objetos `TableKeysAndAttributes` que creó en el paso anterior.

En el siguiente ejemplo de código Java se muestran los pasos anteriores. El ejemplo recupera dos elementos de la tabla `Forum` y tres de la tabla `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);
    }
}
```

### Especificación de parámetros opcionales
<a name="BatchGetItemJavaDocumentAPIOptions"></a>

Junto con los parámetros requeridos, puede especificar también otros opcionales cuando use `batchGetItem`. Por ejemplo, puede proporcionar una expresión `ProjectionExpression` con cada `TableKeysAndAttributes` que defina. Esto le permite especificar los atributos que desea recuperar de la tabla.

En el siguiente ejemplo de código se recuperan dos elementos de la tabla `Forum`. El parámetro `withProjectionExpression` especifica que solamente hay que recuperar el atributo `Threads`.

**Example**  

```
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum")
    .withProjectionExpression("Threads");

forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
```

## Actualización de un elemento
<a name="JavaDocumentAPIItemUpdate"></a>

El método `updateItem` de un objeto `Table` permite actualizar los valores de atributos presentes, agregar atributos nuevos o eliminarlos de un elemento existente. 

El método `updateItem` se comporta de la siguiente manera:
+ Si un elemento no existe (no hay ningún elemento en la tabla con la clave principal especificada), `updateItem` agrega un elemento nuevo a la tabla.
+ Si un elemento ya existe, `updateItem` lleva a cabo la actualización según lo especificado en el parámetro `UpdateExpression`.

**nota**  
También es posible actualizar un elemento mediante `putItem`. Por ejemplo, si llama a `putItem` para agregar un elemento a la tabla pero ya existe uno con la clave principal especificada, `putItem` sustituye el elemento completo. Si hay atributos en el elemento existente que no se especifican en la información de entrada, `putItem` los elimina del elemento.  
En general, recomendamos usar `updateItem` siempre que desee modificar atributos de elementos. El método `updateItem` solo modifica los atributos del elemento que especifique en la información de entrada, pero deja los demás atributos del elemento tal cual estaban.

Siga estos pasos: 

1. Cree una instancia de la clase `Table` para representar la tabla que desea usar.

1. Llame al método `updateTable` de la instancia de `Table`. Debe especificar la clave principal del elemento que desea recuperar, junto con una expresión `UpdateExpression` que describa los atributos que hay que cambiar y cómo modificarlos.

En el siguiente ejemplo de código Java se muestran las tareas anteriores. El código actualiza un elemento de libro en la tabla `ProductCatalog`. Se agrega un nuevo autor al conjunto `Authors` y se elimina el atributo `ISBN` existente. También se reduce el precio en una unidad.

Se utiliza un mapa `ExpressionAttributeValues` en `UpdateExpression`. Los marcadores de posición `:val1` y `:val2` se sustituyen en tiempo de ejecución por los valores reales de `Authors` y `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);
```

### Especificación de parámetros opcionales
<a name="UpdateItemJavaDocumentAPIOptions"></a>

Junto con los parámetros requeridos, puede especificar también parámetros opcionales para el método `updateItem`, incluida una condición que debe cumplirse para que se lleve a cabo la actualización. Si la condición especificada no se cumple, AWS SDK para Java genera una excepción `ConditionalCheckFailedException`. Por ejemplo, el siguiente ejemplo de código Java actualiza de forma condicional el precio de un elemento de libro a 25. Especifica una expresión `ConditionExpression` en la que se indica que el precio solo debe actualizarse si el precio actual es 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>

Puede usar `updateItem` para implementar un contador atómico y aumentar o reducir el valor de un atributo existente sin interferir con las demás solicitudes de escritura. Para incrementar un contador atómico, use una expresión `UpdateExpression` con la acción `set` para sumar un valor numérico a una atributo existente de tipo `Number`.

En el siguiente ejemplo se pone en práctica lo anterior y se incrementa el atributo `Quantity` en una unidad. También se demuestra cómo usar el parámetro `ExpressionAttributeNames` en una expresión `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);
```

## Eliminación de un elemento
<a name="DeleteMidLevelJava"></a>

El método `deleteItem` elimina un elemento de una tabla. Es preciso proporcionar la clave principal del elemento que se desea eliminar.

Siga estos pasos: 

1. Cree una instancia del cliente de `DynamoDB`.

1. Llame al método `deleteItem` proporcionando la clave del elemento que desea eliminar. 

En el siguiente ejemplo de Java se muestran estas tareas.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

DeleteItemOutcome outcome = table.deleteItem("Id", 101);
```

### Especificación de parámetros opcionales
<a name="DeleteItemJavaDocumentAPIOptions"></a>

Puede especificar parámetros opcionales para `deleteItem`. Por ejemplo, el siguiente ejemplo de código Java incluye una expresión `ConditionExpression` que indica que un elemento de libro de `ProductCatalog` solo se puede eliminar si el libro está descatalogado (el atributo `InPublication` es false).

**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);
```

# Ejemplo: operaciones CRUD mediante la API de documentos de AWS SDK para Java
<a name="JavaDocumentAPICRUDExample"></a>

En el siguiente ejemplo de código se ilustran las operaciones CRUD en un elemento de Amazon DynamoDB. En el ejemplo se crea un elemento, se recupera, se llevan a cabo varias actualizaciones y, por último, se elimina.

**nota**  
Además, SDK para Java proporciona un modelo de persistencia de objetos, que le permite mapear las clases del lado del cliente a las tablas de DynamoDB. Este enfoque puede reducir la cantidad de código que hay que escribir. Para obtener más información, consulte [Java 1.x: DynamoDBMapper](DynamoDBMapper.md).

**nota**  
En este ejemplo de código se supone que ya ha cargado datos en DynamoDB para su cuenta siguiendo las instrucciones de la sección [Creación de tablas y carga de datos para ejemplos de código en DynamoDB](SampleData.md).  
Para obtener instrucciones paso a paso acerca de cómo ejecutar el siguiente ejemplo, consulte [Ejemplos 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());
        }
    }
}
```

# Ejemplo: operaciones por lotes mediante la API de documentos de AWS SDK para Java
<a name="batch-operation-document-api-java"></a>

En esta sección se proporcionan ejemplos de operaciones de escritura y obtención por lote en Amazon DynamoDB mediante la API de documentos de AWS SDK para Java.

**nota**  
Además, SDK para Java proporciona un modelo de persistencia de objetos, que le permite mapear las clases del lado del cliente a las tablas de DynamoDB. Este enfoque puede reducir la cantidad de código que hay que escribir. Para obtener más información, consulte [Java 1.x: DynamoDBMapper](DynamoDBMapper.md).

**Topics**
+ [Ejemplo: operación de escritura por lotes mediante la API de documentos de AWS SDK para Java](#JavaDocumentAPIBatchWrite)
+ [Ejemplo: operación de obtención por lotes mediante la API de documentos de AWS SDK para Java](#JavaDocumentAPIBatchGet)

## Ejemplo: operación de escritura por lotes mediante la API de documentos de AWS SDK para Java
<a name="JavaDocumentAPIBatchWrite"></a>

En el siguiente ejemplo de código Java se usa el método `batchWriteItem` para llevar a cabo las siguientes operaciones de colocación y eliminación:
+ Colocar un elemento en la tabla `Forum`.
+ Colocar un elemento y eliminar un elemento de la tabla `Thread`. 

Al crear la solicitud de escritura por lotes, puede especificar cualquier cantidad de solicitudes de colocación y eliminación en una o varias tablas. Sin embargo, `batchWriteItem` limita el tamaño de una solicitud de escritura por lotes y el número de operaciones de colocación y eliminación que se pueden llevar a cabo en una misma operación de escritura por lotes. Si la solicitud supera estos límites, se rechaza la solicitud. Si la tabla no cuenta con suficiente desempeño provisionado para atender esta solicitud, los elementos de solicitud sin procesar se devuelven en la respuesta. 

En el siguiente ejemplo se comprueba la respuesta para saber si contiene elementos de solicitud sin transformar. En caso afirmativo, entra en bucle y vuelve a enviar la solicitud `batchWriteItem` con elementos sin procesar. Si ha seguido los ejemplos de esta guía, ya debería haber creado las tablas `Forum` y `Thread`. También puede crear estas tablas y cargar los ejemplos de datos mediante programación. Para obtener más información, consulte [Creación de ejemplos de tablas y carga de datos utilizando AWS SDK para Java](AppendixSampleDataCodeJava.md).

Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos 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);
        }

    }

}
```

## Ejemplo: operación de obtención por lotes mediante la API de documentos de AWS SDK para Java
<a name="JavaDocumentAPIBatchGet"></a>

En el siguiente ejemplo de código Java se usa el método `batchGetItem` para recuperar varios elementos de las tablas `Forum` y `Thread`. La solicitud `BatchGetItemRequest` especifica los nombres de las tablas y una lista de claves para cada elemento que se desea obtener. En el ejemplo se procesa la respuesta y se imprimen los elementos recuperados.

**nota**  
En este ejemplo de código se supone que ya ha cargado datos en DynamoDB para su cuenta siguiendo las instrucciones de la sección [Creación de tablas y carga de datos para ejemplos de código en DynamoDB](SampleData.md).  
Para obtener instrucciones paso a paso acerca de cómo ejecutar el siguiente ejemplo, consulte [Ejemplos 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());
        }

    }

}
```

# Ejemplo: control de atributos de tipo binario mediante la API de documentos de AWS SDK para Java
<a name="JavaDocumentAPIBinaryTypeExample"></a>

En el siguiente ejemplo se ilustra cómo se controlan los atributos de tipo Binary. Además, se agrega un elemento a la tabla `Reply`. El elemento incluye un atributo de tipo Binary (`ExtendedMessage`) que almacena datos comprimidos. A continuación, en el ejemplo se recupera el elemento y se imprimen todos los valores de los atributos. Con fines ilustrativos, el ejemplo usa la clase `GZIPOutputStream` para comprimir un ejemplo de secuencia y asignársela al atributo `ExtendedMessage`. Cuando se recupera el atributo binario, se descomprime mediante la clase `GZIPInputStream`. 

**nota**  
Además, SDK para Java proporciona un modelo de persistencia de objetos, que le permite mapear las clases del lado del cliente a las tablas de DynamoDB. Este enfoque puede reducir la cantidad de código que hay que escribir. Para obtener más información, consulte [Java 1.x: DynamoDBMapper](DynamoDBMapper.md).

Si ha seguido la sección [Creación de tablas y carga de datos para ejemplos de código en DynamoDB](SampleData.md), seguramente habrá creado ya la tabla `Reply`. También puede crear esta tabla mediante programación. Para obtener más información, consulte [Creación de ejemplos de tablas y carga de datos utilizando AWS SDK para Java](AppendixSampleDataCodeJava.md).

Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos 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;
    }
}
```

# Uso de elementos: .NET
<a name="LowLevelDotNetItemCRUD"></a>

Puede usar la API de bajo nivel AWS SDK para .NET para realizar operaciones típicas de creación, lectura, actualización y eliminación (CRUD, por sus siglas en inglés) en los elementos de una tabla. A continuación se indican los pasos que suelen llevarse a cabo para realizar operaciones CRUD a los datos mediante la API de bajo nivel de .NET:

1. Cree una instancia de la clase `AmazonDynamoDBClient` (el cliente).

1. Proporcione los parámetros requeridos específicos de la operación en el objeto de solicitud correspondiente.

   Por ejemplo, use el objeto de solicitud `PutItemRequest` para cargar un elemento y el objeto de solicitud `GetItemRequest` para recuperar un elemento existente. 

   Puede usar el objeto de solicitud para proporcionar los parámetros necesarios y opcionales. 

1. Ejecute el método apropiado proporcionado por el cliente pasándolo en el objeto de solicitud que ha creado en el paso anterior. 

   El cliente `AmazonDynamoDBClient` proporciona los métodos `PutItem`, `GetItem`, `UpdateItem` y `DeleteItem` para las operaciones CRUD.

**Topics**
+ [Colocación de un elemento](#PutItemLowLevelAPIDotNet)
+ [Obtención de un elemento](#GetItemLowLevelDotNET)
+ [Actualización de un elemento](#UpdateItemLowLevelDotNet)
+ [Contador atómico](#AtomicCounterLowLevelDotNet)
+ [Eliminación de un elemento](#DeleteMidLevelDotNet)
+ [Escritura por lotes: colocación y eliminación de varios elementos](#BatchWriteLowLevelDotNet)
+ [Obtención por lotes: obtención de varios elementos](#BatchGetLowLevelDotNet)
+ [Ejemplo: operaciones CRUD con la API de bajo nivel de AWS SDK para .NET](LowLevelDotNetItemsExample.md)
+ [Ejemplo: operaciones por lotes con la API de bajo nivel de AWS SDK para .NET](batch-operation-lowlevel-dotnet.md)
+ [Ejemplo: control de atributos de tipo binario mediante la API de bajo nivel de AWS SDK para .NET](LowLevelDotNetBinaryTypeExample.md)

## Colocación de un elemento
<a name="PutItemLowLevelAPIDotNet"></a>

El método `PutItem` carga un elemento en una tabla. Si el elemento existe, sustituye el elemento completo.

**nota**  
En lugar de ello, si prefiere actualizar solamente algunos atributos concretos, puede usar el método `UpdateItem`. Para obtener más información, consulte [Actualización de un elemento](#UpdateItemLowLevelDotNet).

A continuación se indican los pasos que hay que seguir para cargar un elemento mediante la API de bajo nivel del SDK para .NET:

1. Cree una instancia de la clase `AmazonDynamoDBClient`.

1. Cree una instancia de la clase `PutItemRequest` para proporcionar los parámetros requeridos.

   Para colocar un elemento, debe proporcionar el nombre de la tabla y el elemento. 

1. Ejecute el método `PutItem` proporcionando el objeto `PutItemRequest` que creó en el paso anterior.

En el siguiente ejemplo de C\$1 se ponen en práctica los pasos anteriores. En el ejemplo se carga un elemento en la tabla `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);
```

En el ejemplo anterior, hemos cargado un elemento de libro que tiene los atributos `Id`, `Title`, `ISBN` y `Authors`. Tenga en cuenta `Id` es un atributo de tipo numérico y demás son de cadena. Autores es un conjunto `String`.

### Especificación de parámetros opcionales
<a name="PutItemLowLevelAPIDotNetOptions"></a>

También puede usar el objeto `PutItemRequest` para proporcionar parámetros opcionales, como se muestra en el siguiente ejemplo de código C\$1. En el ejemplo se especifican los parámetros opcionales siguientes:
+ `ExpressionAttributeNames`, `ExpressionAttributeValues` y `ConditionExpression` especifican que el elemento existente se puede sustituir únicamente si su atributo ISBN tiene un valor específico.
+ `ReturnValues`El parámetro para solicitar el elemento anterior en la respuesta.

**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 obtener más información, consulte [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html).

## Obtención de un elemento
<a name="GetItemLowLevelDotNET"></a>

El método `GetItem` recupera un elemento.

**nota**  
Para recuperar varios elementos, puede usar el método `BatchGetItem`. Para obtener más información, consulte [Obtención por lotes: obtención de varios elementos](#BatchGetLowLevelDotNet).

A continuación se indican los pasos que hay que seguir para recuperar un elemento existente mediante la API de bajo nivel de AWS SDK para .NET.

1. Cree una instancia de la clase `AmazonDynamoDBClient`.

1. Cree una instancia de la clase `GetItemRequest` para proporcionar los parámetros requeridos.

   Para obtener un elemento, debe proporcionar el nombre de la tabla y la clave principal del elemento. 

1. Ejecute el método `GetItem` proporcionando el objeto `GetItemRequest` que creó en el paso anterior.

En el siguiente ejemplo de C\$1 se ponen en práctica los pasos anteriores. En el siguiente ejemplo se recupera un elemento de la tabla `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.
```

### Especificación de parámetros opcionales
<a name="GetItemLowLevelDotNETOptions"></a>

También puede usar el objeto `GetItemRequest` para proporcionar parámetros opcionales, como se muestra en el siguiente ejemplo de código C\$1. En el ejemplo se especifican los parámetros opcionales siguientes:
+ `ProjectionExpression`El parámetro para especificar los atributos que se van a recuperar.
+ `ConsistentRead`El parámetro para realizar una lectura de consistencia alta. Para obtener más información sobre la consistencia de lectura, consulte [Coherencia de lectura de 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 obtener más información, consulte [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html).

## Actualización de un elemento
<a name="UpdateItemLowLevelDotNet"></a>

El método `UpdateItem` actualiza un elemento si existe. Puede usar la operación `UpdateItem` para actualizar los valores de atributos presentes, agregar atributos nuevos o eliminarlos de la colección existente. Si el elemento que tiene clave principal especificada no se encuentra, se agrega un nuevo elemento.

La operación `UpdateItem` se rige por las directrices siguientes:
+ Si el elemento no existe, `UpdateItem` agrega un elemento nuevo utilizando la clave principal especificada en la información de entrada.
+ Si el elemento existe, `UpdateItem` aplica las actualizaciones como se indica a continuación:
  + Sustituye los valores de los atributos existentes por los valores de la actualización.
  + Si el atributo que se proporciona en la información de entrada no existe, agrega un nuevo atributo al elemento.
  + Si el atributo de entrada es null, elimina el atributo, en caso de que esté presente. 
  + Si se utiliza `ADD` para `Action`, puede agregar valores a un conjunto existente (de tipo String Set o Number Set) o bien sumar (si se usa un número positivo) o restar (si se usa un número negativo) matemáticamente un valor del atributo numérico existente.

**nota**  
La operación `PutItem` también puede llevar a cabo una actualización. Para obtener más información, consulte [Colocación de un elemento](#PutItemLowLevelAPIDotNet). Por ejemplo, si llama a `PutItem` para cargar un elemento y la clave principal ya existe, la operación `PutItem` sustituye el elemento completo. Tenga en cuenta que, si hay atributos en el elemento existente que no se especifican en la información de entrada, la operación `PutItem` los eliminará. Sin embargo, `UpdateItem` solo actualiza los atributos de entrada especificados. Todos los demás atributos existentes de ese elemento permanecen inalterados. 

A continuación se indican los pasos que hay que seguir para actualizar un elemento existente mediante la API de bajo nivel del SDK para .NET:

1. Cree una instancia de la clase `AmazonDynamoDBClient`.

1. Cree una instancia de la clase `UpdateItemRequest` para proporcionar los parámetros requeridos.

   Se trata del objeto de solicitud en el que se describen todas las actualizaciones, tales como agregar atributos o actualizar o eliminar atributos existentes. Para eliminar un atributo, especifique su nombre con el valor null. 

1. Ejecute el método `UpdateItem` proporcionando el objeto `UpdateItemRequest` que creó en el paso anterior. 

En el siguiente ejemplo de código C\$1 se ponen en práctica los pasos anteriores. En el ejemplo se actualiza un elemento libro de la tabla `ProductCatalog`. Se agrega un nuevo autor a la colección `Authors` y se elimina el atributo `ISBN` existente. También se reduce el precio en una unidad.



```
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);
```

### Especificación de parámetros opcionales
<a name="UpdateItemLowLevelDotNETOptions"></a>

También puede usar el objeto `UpdateItemRequest` para proporcionar parámetros opcionales, como se muestra en el siguiente ejemplo de código C\$1. En él se especifican los parámetros opcionales siguientes:
+ `ExpressionAttributeValues` y `ConditionExpression` para especificar que el precio solo puede actualizarse si el precio actual es 20.00.
+ `ReturnValues`El parámetro para solicitar el elemento actualizado en la respuesta. 

**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 obtener más información, consulte [UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html). 

## Contador atómico
<a name="AtomicCounterLowLevelDotNet"></a>

Puede usar `updateItem` para implementar un contador atómico y aumentar o reducir el valor de un atributo existente sin interferir con las demás solicitudes de escritura. Para actualizar un contador atómico, use `updateItem` con un atributo de tipo `Number` en el parámetro `UpdateExpression` y use `ADD` como `Action`.

En el siguiente ejemplo se pone en práctica lo anterior y se incrementa el atributo `Quantity` en una unidad.

```
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);
```

## Eliminación de un elemento
<a name="DeleteMidLevelDotNet"></a>

El método `DeleteItem` elimina un elemento de una tabla. 

A continuación se indican los pasos que hay que seguir para eliminar un elemento mediante el API de bajo nivel del SDK para .NET. 

1. Cree una instancia de la clase `AmazonDynamoDBClient`.

1. Cree una instancia de la clase `DeleteItemRequest` para proporcionar los parámetros requeridos.

    Para eliminar un elemento, se requieren el nombre de la tabla y la clave principal del elemento. 

1. Ejecute el método `DeleteItem` proporcionando el objeto `DeleteItemRequest` que creó en el paso 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);
```

### Especificación de parámetros opcionales
<a name="DeleteItemLowLevelDotNETOptions"></a>

También puede usar el objeto `DeleteItemRequest` para proporcionar parámetros opcionales, como se muestra en el siguiente ejemplo de código C\$1. En él se especifican los parámetros opcionales siguientes:
+ `ExpressionAttributeValues` y `ConditionExpression` para especificar que el elemento de libro solo se puede eliminar si está descatalogado (el valor del atributo InPublication es false). 
+ `ReturnValues`El parámetro para solicitar el elemento eliminado en la respuesta.

**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 obtener más información, consulte [DeleteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html).

## Escritura por lotes: colocación y eliminación de varios elementos
<a name="BatchWriteLowLevelDotNet"></a>

La *escritura por lotes* se refiere a colocar y eliminar varios elementos en un lote. El método `BatchWriteItem` permite colocar y eliminar varios elementos de una o varias tablas con una sola llamada. A continuación se indican los pasos que hay que seguir para recuperar varios elementos mediante el API de bajo nivel del SDK para .NET.

1. Cree una instancia de la clase `AmazonDynamoDBClient`.

1. Cree una instancia de la clase `BatchWriteItemRequest` para describir todas las operaciones de colocación y eliminación.

1. Ejecute el método `BatchWriteItem` proporcionando el objeto `BatchWriteItemRequest` que creó en el paso anterior.

1. Procese la respuesta. Debe comprobar si en la respuesta se ha devuelto algún elemento de solicitud sin procesar. Esto puede ocurrir si se alcanza la cuota de rendimiento aprovisionado o se produce algún otro error transitorio. Además, DynamoDB limita el tamaño de la solicitud y el número de operaciones que se pueden especificar en ella. Si supera estos límites, DynamoDB rechaza la solicitud. Para obtener más información, consulte [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html). 

En el siguiente ejemplo de código C\$1 se ponen en práctica los pasos anteriores. En el siguiente ejemplo se crea una solicitud `BatchWriteItemRequest` para realizar las siguientes operaciones de escritura:
+ Colocar un elemento en la tabla `Forum`.
+ Colocar y eliminar un elemento en la tabla `Thread`

A continuación, el código ejecuta `BatchWriteItem` para llevar a cabo una operación por 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 ver un ejemplo práctico, consulte [Ejemplo: operaciones por lotes con la API de bajo nivel de AWS SDK para .NET](batch-operation-lowlevel-dotnet.md). 

## Obtención por lotes: obtención de varios elementos
<a name="BatchGetLowLevelDotNet"></a>

El método `BatchGetItem` permite recuperar varios elementos de una o varias tablas. 

**nota**  
Para recuperar un solo elemento, puede usar el método `GetItem`. 

A continuación se indican los pasos que hay que seguir para recuperar varios elementos mediante la API de bajo nivel AWS SDK para .NET.

1. Cree una instancia de la clase `AmazonDynamoDBClient`.

1. Cree una instancia de la clase `BatchGetItemRequest` para proporcionar los parámetros requeridos.

   Para recuperar varios elementos, es obligatorio indicar el nombre de la tabla y una lista de valores de clave principal. 

1. Ejecute el método `BatchGetItem` proporcionando el objeto `BatchGetItemRequest` que creó en el paso anterior.

1. Procese la respuesta. Debe comprobar si han quedado claves sin procesar, lo que podría ocurrir si se alcanza la cuota de rendimiento aprovisionada o se produce cualquier otro error transitorio.

En el siguiente ejemplo de código C\$1 se ponen en práctica los pasos anteriores. En el ejemplo se recuperan elementos de dos tablas, `Forum` y `Thread`. La solicitud especifica dos elementos en la tabla `Forum` y tres en la tabla `Thread`. La respuesta incluye elementos de ambas tablas. En el código se muestra cómo procesar la respuesta.



```
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);
}
```



### Especificación de parámetros opcionales
<a name="BatchGetItemLowLevelDotNETOptions"></a>

También puede usar el objeto `BatchGetItemRequest` para proporcionar parámetros opcionales, como se muestra en el siguiente ejemplo de código C\$1. En el siguiente ejemplo de código se recuperan dos elementos de la tabla `Forum`. En él se especifica el parámetro opcional siguiente:
+  `ProjectionExpression`El parámetro para especificar los atributos que se van a recuperar.

**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 obtener más información, consulte [BatchGetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html). 

# Ejemplo: operaciones CRUD con la API de bajo nivel de AWS SDK para .NET
<a name="LowLevelDotNetItemsExample"></a>

En el siguiente ejemplo de código C\$1 se ilustran las operaciones de creación, lectura, actualización y eliminación (CRUD, Create, Read, Update and Delete) en un elemento de Amazon DynamoDB. En el ejemplo se agrega un elemento a la tabla `ProductCatalog`, se recupera, se llevan a cabo varias actualizaciones y, por último, se elimina. Si no ha creado esta tabla, también puede crearla mediante programación. Para obtener más información, consulte [Creación de ejemplos de tablas y carga de datos utilizando AWS SDK para .NET](AppendixSampleDataCodeDotNET.md).

Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos 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("************************************************");
        }
    }
}
```

# Ejemplo: operaciones por lotes con la API de bajo nivel de AWS SDK para .NET
<a name="batch-operation-lowlevel-dotnet"></a>

**Topics**
+ [Ejemplo: operación de escritura por lote mediante la API de bajo nivel de AWS SDK para .NET](#batch-write-low-level-dotnet)
+ [Ejemplo: operación de obtención por lotes mediante la API de bajo nivel de AWS SDK para .NET](#LowLevelDotNetBatchGet)

En esta sección se proporcionan ejemplos de las operaciones de *escritura por lote* y *obtención por lote* que Amazon DynamoDB admite.

## Ejemplo: operación de escritura por lote mediante la API de bajo nivel de AWS SDK para .NET
<a name="batch-write-low-level-dotnet"></a>

En el siguiente ejemplo de código C\$1 se usa el método `BatchWriteItem` para llevar a cabo las siguientes operaciones de colocación y eliminación:
+ Colocar un elemento en la tabla `Forum`.
+ Colocar un elemento y eliminar un elemento de la tabla `Thread`. 

Al crear la solicitud de escritura por lotes, puede especificar cualquier cantidad de solicitudes de colocación y eliminación en una o varias tablas. Sin embargo, `BatchWriteItem` de DynamoDB limita el tamaño de una solicitud de escritura por lote y el número de operaciones de colocación y eliminación que se pueden llevar a cabo en una misma operación de escritura por lote. Para obtener más información, consulte [BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html). Si la solicitud supera estos límites, se rechaza la solicitud. Si la tabla no cuenta con suficiente desempeño provisionado para atender esta solicitud, los elementos de solicitud sin procesar se devuelven en la respuesta. 

En el siguiente ejemplo se comprueba la respuesta para saber si contiene elementos de solicitud sin transformar. En caso afirmativo, entra en bucle y vuelve a enviar la solicitud `BatchWriteItem` con elementos sin procesar. También puede crear estos ejemplos de tablas y cargar los ejemplos de datos mediante programación. Para obtener más información, consulte [Creación de ejemplos de tablas y carga de datos utilizando AWS SDK para .NET](AppendixSampleDataCodeDotNET.md).

Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos 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);
        }
    }
}
```

## Ejemplo: operación de obtención por lotes mediante la API de bajo nivel de AWS SDK para .NET
<a name="LowLevelDotNetBatchGet"></a>

En el siguiente ejemplo de código C\$1 se usa el método `BatchGetItem` para recuperar varios elementos de las tablas `Forum` y `Thread` en Amazon DynamoDB. La solicitud `BatchGetItemRequest` especifica los nombres de las tablas y una lista de claves principales para cada tabla. En el ejemplo se procesa la respuesta y se imprimen los elementos recuperados. 

Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos 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("************************************************");
        }
    }
}
```

# Ejemplo: control de atributos de tipo binario mediante la API de bajo nivel de AWS SDK para .NET
<a name="LowLevelDotNetBinaryTypeExample"></a>

En el siguiente ejemplo de código C\$1 se ilustra cómo se controlan los atributos de tipo Binary. Además, se agrega un elemento a la tabla `Reply`. El elemento incluye un atributo de tipo Binary (`ExtendedMessage`) que almacena datos comprimidos. A continuación, en el ejemplo se recupera el elemento y se imprimen todos los valores de los atributos. Con fines ilustrativos, el ejemplo usa la clase `GZipStream` para comprimir un ejemplo de secuencia y asignársela al atributo `ExtendedMessage`; después, la descomprime al imprimir el valor del atributo. 

Para obtener instrucciones paso a paso para probar el siguiente ejemplo, consulte [Ejemplos 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();
            }
        }
    }
}
```