2016-01-18 2 views
1

Я пытаюсь использовать токен продолжения из ответа query_entities, чтобы получить следующие 1000 значений, но я получаю тот же самый 1000 назад.Azure table storage - using next_row_key возвращает тот же кусок

Мой код

rows = table_service.query_entities(
    'tableName', "PartitionKey eq '6'", top=1000) 

nextRowKey = rows.x_ms_continuation['NextRowKey'] 

rows = table_service.query_entities(
    'tableName', "PartitionKey eq '6'", 
    next_row_key=nextRowKey, top=1000) 

я делаю что-то не так? Из объяснения в github кажется, что он должен работать.

+1

Когда вы получите токен продолжения, вы получите как «NextPartitionKey», так и «NextRowKey». Попробуйте использовать их оба при получении следующего набора объектов. Это должно сработать! –

+0

Вы правы, я не мог догадаться! Если вы скомпилируете ответ, я отвечу на вопрос как ответ. Благодарю. – LetsPlayYahtzee

ответ

1

Когда таблица служба возвращает маркер продолжения, вы получите две вещи обратно - NextPartitionKey и NextRowKey. Чтобы получить следующий набор объектов, вам нужно будет использовать их оба. Пожалуйста, сделать что-то вроде следующего:

rows = table_service.query_entities(
    'tableName', "PartitionKey eq '6'", top=1000) 

nextRowKey = rows.x_ms_continuation['NextRowKey'] 
nextPartitionKey = rows.x_ms_continuation['NextPartitionKey'] 

rows = table_service.query_entities(
    'tableName', "PartitionKey eq '6'", next_partition_key=nextPartitionKey, 
    next_row_key=nextRowKey, top=1000) 
-1

Это временное решение, которое решает эту проблему. Поскольку я не могу использовать токен продолжения для захвата следующего ключа строки, я обновляю запрос, используя последний ключ строки вручную, и я использую токен продолжения только как условие завершения.

Ниже приведен пример запроса диапазона. Предположим, что мы хотим получить все значения между клавишами строк 123456789 и 123457689, которые охватывают диапазон более 1000 строк.

rows = table_service.query_entities(
    'tableName', ("PartitionKey eq '6' Rowkey gt '123456789' and " 
        "Rowkey lt '123457689'"), top=1000) 

data = rows 

while hasattr(rows, 'x_ms_continuation'): 
    # now using the last retrieved rowkey inside the query 
    rows = table_service.query_entities(
     'tableName', ("PartitionKey eq '6' Rowkey gt '" + 
         rows[len(rows)-1].RowKey + "' and " 
         "Rowkey lt '123457689'"), top=1000) 
    data.extend(rows) 
+0

См. Комментарий Гаурава. Вы просто не отправляете оба компонента токена продолжения. –

+0

Вы понимаете, что здесь отсутствует документация, верно? Я не думаю, что разумно ожидать, что кто-то только догадался бы об этом. – LetsPlayYahtzee

+0

Если вы посмотрите [docs для query_entites] (https://github.com/Azure/azure-storage-python/blob/master/azure/storage/table/tableservice.py#L399), они говорят, как их получить от результата последней операции листинга и как передать их. При этом мы добавляем более удобную обработку токенов продолжения в следующей версии. –

1

Ниже приводится образец, который работает для меня (использует 0.33.0 лазурного хранения), единственное улучшение, я хотел бы видеть, как лучше сочетать наборы результатов.

def GetData(tableService, tableName, dataFilter): 
    #https://github.com/Azure/azure-storage-python/blob/master/azure/storage/table/tableservice.py 
    keyMarkers = {} 
    keyMarkers['nextpartitionkey'] = 0 
    keyMarkers['nextrowkey'] = 0 
    b=[] 
    while True: 
     #get a batch of data 
     a = tableService.query_entities(table_name=tableName, filter=dataFilter,num_results=1000 ,marker=keyMarkers) 
     #copy results to list 
     for item in a.items: 
      b.append(item) 
     #check to see if more data is available 
     if len(a.next_marker) == 0: 
      del a 
      break 
     #if more data available setup current position 
     keyMarkers['nextpartitionkey'] = a.next_marker['nextpartitionkey'] 
     keyMarkers['nextrowkey'] = a.next_marker['nextrowkey'] 
     #house keep temp storage 
     del a 
    #return final list 
    return b