Bueno, como sugiere el título, quiero consultar en mi tabla DynamoDB usando GSI con la clave principal y la clave de clasificación (ambas de GSI). Intenté algunas formas de hacerlo, pero no tuve éxito.

Tengo una tabla con url-date-index, url es la clave principal de GSI y date es la clave de clasificación.

Intenté lo siguiente:

  1. Usando KeyConditionExpression con & comparador:

    Este me recuperó el error: TypeError: expected string or bytes-like

boto3.resource('dynamodb').Table('table').query(
    IndexName='url-date-index',
    KeyConditionExpression=conditions.Key('url')).eq(url) & conditions.Key('date')).eq(date)
)
  1. Usando KeyConditionExpression y FilterExpression:

    Esto recuperó el siguiente error: Filter Expression can only contain non-primary key attributes

boto3.resource('dynamodb').Table('table').query(
    IndexName='url-date-index',
    KeyConditionExpression=conditions.Key('url')).eq(url),
    FilterExpression=conditions.Key('date')).eq(date)
)
  1. Usando ExpressionAttributeNames, ExpressionAttributeValues y KeyConditionExpression:

    Esto devolvió cualquier cosa, incluso no el elemento que coincide con url y date en la tabla.

boto3.resource('dynamodb').Table('table').query(
    IndexName='url-date-index',
    ExpressionAttributeNames={
        '#n0': 'url',
        '#n1': 'date'
    },
    ExpressionAttributeValues={
        ':v0': url,
        ':v1': date
    },
    KeyConditionExpression='(#n0 = :v0) AND (#n1 = :v1)'
)

¿Alguien sabe qué estoy haciendo mal o qué puedo hacer para que esto funcione?

1
João Koritar 13 mar. 2021 a las 04:52

2 respuestas

La mejor respuesta

En su caso de uso particular, querrá usar ExpressionAttributeNames ya que los nombres de sus atributos url y date son palabras reservadas en DynamoDB.

Los documentos de DynamoDB sobre consultas de idnexes secundarios ofrecen un ejemplo de consulta debidamente estructurada, que podemos aplicar a su situación:

Usando esto como una guía, podemos construir cómo deberían verse los argumentos para su operación de consulta. Por ejemplo

 {
    "TableName": "table",
    "IndexName": "url-date-index",
    "KeyConditionExpression": "#pk = :pk And #sk = :sk",
    "ExpressionAttributeNames": {"#pk":"url","#sk":"date"},
    "ExpressionAttributeValues": {":pk": {"S":url},":sk": {"S":date}}}
}

Si esto aún no funciona para usted, considere revisar el NoSQL Workbench Para DynamoDB. Entre sus muchas funciones útiles, tiene un Operation Builder que le ayuda a construir operaciones de DynamoDB mediante una interfaz gráfica. Incluso puede ejecutar la operación contra su base de datos en vivo. Una vez que tenga la operación funcionando como desea, la herramienta puede traducir la operación en una muestra completa de código Phython, Javascript (Node) o Java, que puede usar para ver cómo se construye la operación.

1
Seth Geoghegan 13 mar. 2021 a las 16:29

consulta es una función con algunos argumentos con nombre (IndexName, KeyConditionExpression, ...).

Intentemos llamar a la función con argumentos nombrados como una función normal:

boto3.resource('dynamodb').Table('table').query(
    IndexName='url-date-index', 
    KeyConditionExpression=conditions.Key('url')).eq(url) & conditions.Key('date')).eq(date)
)
1
hoangdv 13 mar. 2021 a las 02:10