Nombres de atributos de expresión en DynamoDB
Un nombre de atributo de expresión es un 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 y 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). Para obtener ejemplos de código específicos de los lenguajes de programación, consulte Introducción a DynamoDB y los SDK de AWS.
Temas
Palabras reservadas
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.
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
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 Especificación de atributos de elementos mediante expresiones).
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
Supongamos que desea obtener acceso al atributo anidado ProductReviews.OneStar
, utilizando la siguiente expresión de proyección.
aws dynamodb get-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"123"}}' \ --projection-expression "ProductReviews.OneStar"
El resultado podría contener todas las opiniones sobre productos de una sola estrella, que es lo previsto.
Pero ¿qué sucedería si utiliza en su lugar un nombre de atributo de expresión? Por ejemplo, ¿qué ocurriría si definiese #pr1star
como sustituto de ProductReviews.OneStar
?
aws dynamodb get-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"123"}}' \ --projection-expression "#pr1star" \ --expression-attribute-names '{"#pr1star":"ProductReviews.OneStar"}'
DynamoDB podría devolver un resultado vacío, en lugar del mapa previsto de opiniones de una sola estrella. Esto se debe a que DynamoDB interpreta un punto en el nombre de un atributo de expresión como un carácter del nombre del atributo. Cuando DynamoDB evalúa el nombre de atributo de expresión #pr1star
, determina que ProductReviews.OneStar
hace referencia a un atributo escalar, que no es lo que estaba previsto.
El enfoque correcto consiste en definir un nombre de atributo de expresión para cada componente 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.
Repetición de nombres de atributos
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 #
.