将数据从BigQuery导出到GCS - 可以进行部分传输吗?

时间:2015-02-27 19:54:21

标签: asynchronous export google-bigquery google-cloud-storage callblocking

我正在将我的数据(从Bigquery中的目标表)导出到GCS中的存储桶。使用Bigquery API以编程方式执行此操作。

将数据从Bigquery导出到GCS时存在约束 - 数据不应大于1GB。

  • 由于目标表中的数据超过1GB,我将文件分成多个部分。
  • 文件将被拆分的部分数量显然取决于我在目标表中的数据大小。

以下是函数exportDataToGCS()的代码片段,其中发生了这种情况:

http = authorize();
bigquery_service = build('bigquery', 'v2', http=http)

    query_request = bigquery_service.jobs()

    DESTINATION_PATH = constants.GCS_BUCKET_PATH + canonicalDate + '/'
    query_data = {
                'projectId': 'ga-cnqr',
                'configuration': {
                                'extract': {
                                        'sourceTable': {
                                                    'projectId': constants.PROJECT_ID,
                                                    'datasetId': constants.DEST_TABLES_DATASET_ID,
                                                    'tableId': canonicalDate,
                                                        },
                                        'destinationUris': [DESTINATION_PATH + canonicalDate + '-*.gz'],
                                        'destinationFormat': 'CSV',
                                        'printHeader': 'false',
                                        'compression': 'GZIP'
                                            }
                                }
                  }

    query_response = query_request.insert(projectId=constants.PROJECT_NUMBER,
                                     body=query_data).execute()

执行此功能后,在我的GCS存储桶中,我的文件以下列方式显示:

File parts in GCS bucket after exporting from BigQuery

但是,我很想知道是否有任何情况下文件应该分成10个部分,但由于上述功能失败,只有3个部分进入存储桶。

那是否可以部分出口?

网络丢失或运行该功能的进程被杀等原因会导致这种情况吗?这个过程是阻塞电话吗?异步?

提前致谢。

更新1:查询响应中的状态参数

这就是我检查DONE状态的方法。

while True:
        status = query_request.get(projectId=constants.PROJECT_NUMBER, jobId=query_response['jobReference']['jobId']).execute()
        if 'DONE' == status['status']['state']:
            logging.info("Finished exporting for the date : " + stringCanonicalDate);
            return

1 个答案:

答案 0 :(得分:4)

如果作业在执行过程中因某种原因失败,则可以进行部分导出。

如果作业处于DONE状态,且作业中没有错误,则表示所有数据都已导出。

我建议在轮询完成作业之前稍等一下 - 如果轮询太快,可以达到速率限制错误,并且考虑到这些异步作业不是很快,不需要毫秒精度。

使用示例代码,以下是测试是否存在错误的方法:

while True:
    status = query_request.get(projectId=constants.PROJECT_NUMBER, jobId=query_response['jobReference']['jobId']).execute() 
    if 'DONE' == status['status']['state']:
        if 'errorResult' in status['status']:
            logging.error("Error exporting for the date : " + stringCanonicalDate);
            logging.error(status['status']['errorResult'])
            return False
        logging.info("Finished exporting for the date : " + stringCanonicalDate);
        return True
    time.sleep(1)

要成为超级健壮的,您还可以捕获在轮询等待循环中偶尔会发生的HTTP错误。看起来你正在使用python apiclient,它会在这种失败时引发apiclient.errors.HttpError