Как я могу запросить таблицу DynamoDB2 по глобальному вторичному индексу только с помощью boto 2.25.0?


Это продолжение моего стремления перейти от обычных таблиц DynamoDB к таблицам DynamoDB2 с глобальными вторичными индексами.

Итак, я создал свою таблицу, как показано на рисунке здесь а затем добавил следующие два элемента:

table.put_item(data={'firstKey': 'key01', 'message': '{"firstKey":"key01", "comments": "mess 1 w/o secondKey"}'})
table.put_item(data={'firstKey': 'key02', 'secondKey':'skey01', 'message': '{"firstKey":"key02", "parentId":"skey01", "comments": "mess 2 w/ secondKey"}'})

, что я хочу сделать сейчас-это извлечь элементы любой из их (я) уникальная firstKey значений или (II) уникальная secondKey значения. 1-й из них прост:

res1 = table.get_item(firstKey='key01')
res1['message']

Я не могу понять, как сделать второй. Это не так работа:

res2 = table.get_item(secondKey='skey01')

Производство The provided key element does not match the schema. Хорошо, это ожидаемо. Когда я делаю это:

res2 = table.query(secondKey='skey01',index='secondKeyIndex')

Я получаю You must specify more than one key to filter on.

Так как же заставить его работать? Заметьте, что когда у меня есть значение secondKey элемента, я не знаю его соответствующего firstKey.

===== UPDATE: вот еще несколько вещей, которые я пробовал:

Это

res2 = table.query(secondKey__eq='skey01',index='secondKeyIndex')

Произведено

boto.dynamodb2.exceptions.QueryError: You must specify more than one key to filter on.

В блоке ниже оператор query не произвел никаких ошибок

res2 = table.query(secondKey='skey01',secondKey__eq='skey01',index='secondKeyIndex')
for r in res2:
    print res2['secondKey']

Но print дал мне

boto.dynamodb2.exceptions.UnknownFilterTypeError: Operator 'secondKey' from 'secondKey' is not recognized.
3 4

3 ответа:

Это возможно с помощью LSI/GSI.

Смотрите учебник по бото здесь (найдите LSI, и вы получите пример). DynamoDB2-boto v2.25.0 : http://boto.readthedocs.org/en/latest/ref/dynamodb2.html

Добавление полного рабочего примера (пробовал с dynamo local: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tools.DynamoDBLocal.html)

conn = DynamoDBConnection(
    host='localhost',
    port=8000,
    aws_access_key_id='DEVDB', #anything will do
    aws_secret_access_key='DEVDB', #anything will do
    is_secure=False)
tables = conn.list_tables()
print "Before Creation:", tables

table_name = 'myTable'
if table_name not in tables['TableNames']:
    Table.create(table_name
        , schema=[HashKey('firstKey')]
        , throughput={'read': 5, 'write': 2}
        , global_indexes=[
            GlobalAllIndex('secondKeyIndex', parts=[HashKey('secondKey')], throughput={'read': 5, 'write': 3})]
        , connection=conn
    )
    #print_table_details(conn, table_name)
table = Table(table_name, connection=conn)
item = Item(table, data={
    'firstKey': str(uuid.uuid4()),
    'secondKey': 'DUMMY-second'
})
item.save()
results = table.query(secondKey__eq='DUMMY-second', index='secondKeyIndex')
for res in results:
    print res['firstKey'], res['secondKey']

Результатом выполнения является:

91d4d056-1da3-42c6-801e-5b8e9c42a93f DUMMY-second
15c17b09-4975-419a-b603-427e4c765f03 DUMMY-second
dd947b7d-935e-458f-84d3-ed6cd4f32f5a DUMMY-second

Также добавление точных пакетов (из-за Dynamo1 / 2 - есть вероятность ошибки):

from boto.dynamodb2.fields import HashKey, RangeKey, GlobalAllIndex
from boto.dynamodb2.layer1 import DynamoDBConnection
from boto.dynamodb2.table import Table
from boto.dynamodb2.items import Item

Для всех тех, кто ищет новую версию при использовании query_2: Проверьте https://github.com/boto/boto/issues/2708

Аргументы запроса форматируются по-разному. Я не пробовал, но я считаю, что синтаксис должен быть:

res2 = table.query(secondKey__eq='skey01',index='secondKeyIndex')