【问题标题】:Azure table storage php pagination not workingAzure表存储php分页不起作用
【发布时间】:2018-06-05 11:17:35
【问题描述】:

我是 azure table storage 的新手,我正在使用 php 构建一个带有分页链接的表,其中包含来自 azure table storage 的数据。例如,您可以检查here。在 1000 条记录之前一切正常,但是当我转到 1010 条记录时,它会返回此错误:-

失败:代码:400 值:错误请求详细信息(如果有): {"odata.error":{"code":"InvalidInput","message":{"lang":"en-US","value":"一个 的请求输入无效。

所以示例queryPaginationEntitiesSample function {$options->setTop($numPerPage * ($page-1));} 中的这段代码导致了这个错误。有人可以帮我解决这个问题吗?

function queryPaginationEntitiesSample($tableClient,$tableName,$numPerPage,$page,$filter) { 
    try { 
        $options = new QueryEntitiesOptions(); 
        $options->setFilter(Filter::applyQueryString($filter)); 
        if($page==1){ 
            $options->setTop($numPerPage);
            $options->setSelectFields(array('PartitionKey','RowKey','Timestamp'));  
            $result = $tableClient->queryEntities($tableName, $options); 
            $entities = $result->getEntities(); 
        } else{ 

             //skip $numPerPage * ($page-1) records 
            $options->setTop($numPerPage * ($page-1)); 
            $options->setSelectFields(array('PartitionKey','RowKey','Timestamp')); 
            $result = $tableClient->queryEntities($tableName, $options); 
            $nRowKey = $result->getNextRowKey(); 
            $nPartitionKey = $result->getNextPartitionKey(); 
            $options = new QueryEntitiesOptions(); 
            $options->setFilter(Filter::applyQueryString($filter)); 
            $options->setTop($numPerPage); 
            $options->setNextRowKey($nRowKey); 
            $options->setNextPartitionKey($nPartitionKey);  
            $result = $tableClient->queryEntities($tableName, $options); 
            $entities = $result->getEntities(); 
        }
        return $entities; 
    }catch(ServiceException $e){ 
        $code = $e->getCode(); 
        $error_message = $e->getMessage(); 
        echo $code.": ".$error_message.PHP_EOL; 
        return null; 
    } 
} 

【问题讨论】:

  • $numPerPage 设置的值是多少?
  • $numPerPage 设置为 10
  • 我也在使用 JasonGrimes\Paginator 进行分页
  • 请编辑您的问题并包含您正在使用的代码。
  • 我现在添加了完整的分页功能

标签: php azure pagination


【解决方案1】:

可以在对表服务的单个请求中获取的最大实体为 1000。由于您要求表服务返回 1010 实体,因此您会收到此错误。

我认为您需要以某种方式更改您的逻辑(抱歉,我不太熟悉 PHP,因此无法提供代码)。但本质上,您需要将延续令牌(下一个 PartitionKey 和下一个 RowKey)与实体一起返回,并将这些值传递给 queryPaginationEntitiesSample 方法并使用它们。

请参阅azure table storage pagination for request 10 items each time 作为参考(解决方案在.Net 中)。

【讨论】:

  • 有没有办法跳过记录并获取下一个记录?
  • 我已将每页记录设置为 10,因此在第 101 页之前一切正常,此时 setTop 设置为 1000,但是当我请求第 102 页时 setTop 设置为 1010 并且出现错误,所以请给我一些想法,如何在第 101 页之后将 setTop 设置为 1000?我也可以获得下一个分区键和下一个行键,但是在第 102 页时它会中断
【解决方案2】:

您的主要问题是您试图在每次迭代中修改$top 的值,这与SKIP 不同

来自此处的文档:https://docs.microsoft.com/en-us/rest/api/storageservices/querying-tables-and-entities

$top 仅返回集合中前 n 个表或实体。

基本上你需要获取延续令牌并提供相同过滤器和$top每次。

您目前正在做的是有效地增加每“页面”数据所需的结果数量。例如,$top 为 10:

Page 1: 10 entries retrieved. 10 total entries retrieved.
Page 2: 10 entries retrieved. 20 total entries retrieved.
Page 3: 20 entries retrieved. 40 total entries retrieved.
Page 4: 30 entries retrieved. 70 total entries retrieved.
...
Page 99: 990 entries retrieved. 49510 total entries retrieved.
Page 101: 1000 entries retrieved. 50510 total entries retrieved.
Page 102: 1010 entries attempted. <-- Not allowed by design.

【讨论】:

    【解决方案3】:

    这里有一个获取所有行的示例代码:

    $entities = ListAzureTable("mytable", "(PartitionKey eq 'XXXX')");
    
    function ListAzureTable($table, $stringFilter)
    {
        global $tableRestProxy;
        
        $options = new QueryEntitiesOptions();
        $filter  = new QueryStringFilter($stringFilter);
        $options->setFilter($filter);
        $result = $tableRestProxy->queryEntities($table, $options);
        $entities = $result->getEntities();
        $nextPK = $result->getNextPartitionKey();
        $nextRK = $result->getNextRowKey();
        
        while ($nextPK != null && $nextPK != "")
        {
            $options = new QueryEntitiesOptions();
            $options->setFilter($filter);
            $options->setNextPartitionKey($nextPK);
            $options->setNextRowKey($nextRK);
            $result = $tableRestProxy->queryEntities($table, $options);
            $nextPK=$result->getNextPartitionKey();
            $nextRK=$result->getNextRowKey();
            $newentities=$result->getEntities();
            
            $entities=array_merge($newentities, $entities);
        }
        
        return $entities;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-10
      • 2021-10-28
      • 2018-12-16
      • 2019-11-17
      相关资源
      最近更新 更多