【问题标题】:Google BigQuery Incomplete Query Replies on Odd AttemptsGoogle BigQuery 对奇怪尝试的不完整查询回复
【发布时间】:2013-07-19 17:17:58
【问题描述】:

当通过 python api 查询 BigQuery 时:

service.jobs().getQueryResults

我们发现第一次尝试运行良好 - 所有预期结果都包含在响应中。但是,如果查询在第一次运行后不久(大约在 5 分钟内)运行第二次,则几乎会立即返回一小部分结果(以 2 的幂),没有错误。

在以下位置查看我们的完整代码: https://github.com/sean-schaefer/pandas/blob/master/pandas/io/gbq.py

有什么可能导致这种情况的想法吗?

【问题讨论】:

    标签: python google-bigquery google-api-python-client


    【解决方案1】:

    看起来问题是我们为 query() 和 getQueryResults() 返回了不同的默认行数。因此,根据您的查询是否快速完成(因此您不必使用 getQueryResults()),您将获得更多或更少的行。

    我已经提交了一个错误,我们应该很快就会修复。

    解决方法(也是一个好主意)是为查询和 getQueryResults 调用设置 maxResults。如果您需要很多行,您可能需要使用返回的页面令牌对结果进行分页。

    以下是从已完成的查询作业中读取一页数据的示例。它将包含在 bq.py 的下一个版本中:

    class _JobTableReader(_TableReader):
      """A TableReader that reads from a completed job."""
    
      def __init__(self, local_apiclient, project_id, job_id):
        self.job_id = job_id
        self.project_id = project_id
        self._apiclient = local_apiclient
    
      def ReadSchemaAndRows(self, max_rows=None):
        """Read at most max_rows rows from a table and the schema.
    
        Args:
          max_rows: maximum number of rows to return.
    
        Raises:
          BigqueryInterfaceError: when bigquery returns something unexpected.
    
        Returns:
          A tuple where the first item is the list of fields and the
          second item a list of rows.
        """
        page_token = None
        rows = []
        schema = {}
        max_rows = max_rows if max_rows is not None else sys.maxint
        while len(rows) < max_rows:
          (more_rows, page_token, total_rows, current_schema) = self._ReadOnePage(
              max_rows=max_rows - len(rows),
              page_token=page_token)
          if not schema and current_schema:
            schema = current_schema.get('fields', {})
    
          max_rows = min(max_rows, total_rows)
          for row in more_rows:
            rows.append([entry.get('v', '') for entry in row.get('f', [])])
          if not page_token and len(rows) != max_rows:
              raise BigqueryInterfaceError(
                'PageToken missing for %r' % (self,))
          if not more_rows and len(rows) != max_rows:
            raise BigqueryInterfaceError(
                'Not enough rows returned by server for %r' % (self,))
        return (schema, rows)
    
      def _ReadOnePage(self, max_rows, page_token=None):
        data = self._apiclient.jobs().getQueryResults(
            maxResults=max_rows,
            pageToken=page_token,
            # Sets the timeout to 0 because we assume the table is already ready.
            timeoutMs=0,
            projectId=self.project_id,
            jobId=self.job_id).execute()
        if not data['jobComplete']:
          raise BigqueryError('Job %s is not done' % (self,))
        page_token = data.get('pageToken', None)
        total_rows = int(data['totalRows'])
        schema = data.get('schema', None)
        rows = data.get('rows', [])
        return (rows, page_token, total_rows, schema)
    

    【讨论】:

    • 您有使用页面令牌的示例吗?我们找到了文档页面:developers.google.com/bigquery/docs/data#paging,但它没有任何代码示例。这对我们的代码来说似乎很重要,因为每页的最大结果有一个硬性上限。
    • 另外,这是 API 错误还是后端错误?我们似乎仍然拥有它,所以一旦完成,我们需要拉一个更新的版本吗?
    • 修复完全在 BigQuery 后端。它应该在昨天上线。
    • 如果您仍然看到意外行为,您能否提供查询的作业 ID?
    • 昨天我们似乎仍然遇到问题,但目前我们不输出作业 ID。我们可以做出改变并就此与您联系。与此同时,我们仍然对是否有任何在 python 中使用分页的示例感兴趣。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-09
    • 2011-01-10
    • 2012-04-17
    • 1970-01-01
    • 2012-04-24
    相关资源
    最近更新 更多