在适用于 PHP 的 Google BigQuery API 中捕获“响应太大而无法返回错误”的正确方法是啥?

Posted

技术标签:

【中文标题】在适用于 PHP 的 Google BigQuery API 中捕获“响应太大而无法返回错误”的正确方法是啥?【英文标题】:What is the proper way to capture a "Response too large to return error" in Google BigQuery API for PHP?在适用于 PHP 的 Google BigQuery API 中捕获“响应太大而无法返回错误”的正确方法是什么? 【发布时间】:2016-01-14 11:20:39 【问题描述】:

在 Google BigQuery 网络界面中,如果我运行的查询返回的响应过大,我会收到以下消息:

错误:响应太大而无法返回。考虑在作业配置中将 allowLargeResults 设置为 true。

在运行作业配置中未设置 allowLargeResults 的查询时,如何在 Google BigQuery API 界面中捕获此错误消息?

【问题讨论】:

【参考方案1】:

在相应的 BigQuery API - Jobs: get 中,此信息位于 status.errorResult 分别在reason 属性:responseTooLargemessage 属性:响应太大而无法返回。考虑在您的作业配置中将 allowLargeResults 设置为 true。欲了解更多详情,...

您还可以查看 status.errors 以了解在作业执行期间遇到的所有错误的更多详细信息

【讨论】:

【参考方案2】:

我们使用这个片段来处理错误,它提供了帮助:

我们在放置作业时也有,然后当我们循环检查作业的状态时,当作业完成时会弹出错误。

try 
                try 
                    $job = $bq->jobs->insert(PROJECT_ID, $job);
                 catch (Google_IO_Exception $e) 
                    $this->e('Exception: ' . $e->getMessage(), 'red');
                    $this->e('Strace: ' . $e->getTraceAsString());
                    if ($e->getMessage() == 'SSL connect error') 
                        $this->clearTokenFile();
                        $this->releaseJob();
                    
                    return false;
                

                $status = new Google_Service_Bigquery_JobStatus();
                $status = $job->getStatus();

                if (0 != $status->count()) 
                    $err_res = $status->getErrorResult();
                    $this->e($err_res->getMessage(), 'red');

                    return false;
                
             catch (Google_Service_Exception $e) 
                $this->e('Exception: ' . $e->getMessage(), 'red');
                return false;
            

on和insertAll我们有,这里注意reason字段:

try 
            $resp = new Google_Service_Bigquery_TableDataInsertAllResponse();
            $resp = $bq->tabledata->insertAll($project_id, $dataset_id, static::tableId(), $request);
            $errors = new Google_Service_Bigquery_TableDataInsertAllResponseInsertErrors();
            $errors = @$resp->getInsertErrors();
            if (!empty($errors)) 
                $error_msg = "\r\nRequest Headers: \r\n" . json_encode($client->request->getRequestHeaders()) . "\r\nResponse Headers: \r\n" . json_encode($client->request->getResponseHeaders()) . "\r\nRequest Body:\r\n" . $client->request->getPostBody() . "\r\nResponse Body:\r\n" . $client->request->getResponseBody() . "\r\n";
                if (is_array($errors)) 
                    foreach ($errors as $eP) 
                        $arr = $eP->getErrors();
                        $line = $eP->getIndex();
                        if (is_array($arr)) 
                            foreach ($arr as $e) 
                                switch ($e->getReason()) 
                                    case "stopped":
                                        break;
                                    case "timeout":
                                        $failed_lines[] = $line;
                                        $last_reason = $e->getReason();
                                        $error_msg.= sprintf("Timeout on line %s, reason: %s, msg: %s\r\n", $line, $e->getReason(), $e->getMessage());
                                        break;
                                    default:
                                        $error_msg.= sprintf("Error on line %s, reason: %s, msg: %s\r\n", $line, $e->getReason(), $e->getMessage());
                                        break;
                                
                            
                         else 
                            $error_msg.= json_encode($arr) . "\r\n";
                        
                    
                    $this->setErrorMessage($error_msg);
                 else 
                    $this->setErrorMessage($errors);
                
                //print_r($errors);
                //exit;
                $success = false;
            
            return $ret;
         catch (Google_Service_Exception $e) 
            $this->setErrors($e->getErrors())->setErrorMessage($e->getMessage());
            throw $e;
        

【讨论】:

【参考方案3】:

回答我自己的问题:以下是为我解决问题的摘要。总之,我无法让它为同步查询抛出错误,但能够让它为异步查询抛出错误。

这是一个响应太大而无法返回的示例查询:

$query = "SELECT * FROM [publicdata:samples.github_timeline] LIMIT 1000000;"

同步查询

使用 jobs.query 运行同步查询:

try 
  $query_request = new Google_Service_Bigquery_QueryRequest();
  $query_request->setQuery($query);
  $res = $this->gbq_service->jobs->query($this->_project_id, $query_request);
  return $res;
 catch (Exception $e)
  echo $e->getMessage());

我收到的回复是:


  "cacheHit": null,
  "jobComplete": false,
  "kind": "bigquery#queryResponse",
  "pageToken": null,
  "totalBytesProcessed": null,
  "totalRows": null

所以在这种情况下,我仍然没有收到所需的“响应太大而无法返回”。

异步查询

如果我将作业作为异步查询运行,作业状态最终会设置为 DONE,并且在检查结果时会抛出错误消息:


  "error": "Error calling GET https://www.googleapis.com/bigquery/v2/projects/.../queries/job_2VICoK6yX0YMM_zRkJ10hT9mom8?timeoutMs=1000000&maxResults=100: (403) Response too large to return. Consider setting allowLargeResults to true in your job configuration. For more information, see https://cloud.google.com/bigquery/troubleshooting-errors",

告诉我需要将结果保存为表格并将 allowLargeResults 设置为 true。

因此,简短的回答是 - 将您的查询作为异步查询运行。

更新

我已经联系了 google,他们提到这可能是 php api 中的错误。他们说会转发给php gbq API的人。

【讨论】:

@rmg 您应该编辑您的原始问题并使用新问题进行更新。这不是一个论坛。而您在此处发布的内容是 ANSWER 类型,因此将被删除。 感谢您的意见。我回答了我自己的问题,因为其他两个答案实际上并没有解决问题,尽管它们确实帮助我弄清楚了发生了什么。在三个答案中,这一个应该是有类似问题的用户的最佳答案。

以上是关于在适用于 PHP 的 Google BigQuery API 中捕获“响应太大而无法返回错误”的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

php 适用于WP的Google Analytics信息中心(GADWP)::如何排除显示跟踪代码的特定网页

适用于 Google Bigquery 的 Oauth 2.0

适用于高级 PHP 开发人员的 MVC [关闭]

在使用适用于 iOS 的 Google Maps SDK 和适用于 iOS 的 Google Places 时,我找不到在哪里可以获得 POI 结果

适用于 Android 的 Google+ 登录 - Google 权限活动结果代码

适用于 Android 的 Google Places API 未显示