使用 Google Apps 脚本设置压缩查询导出

Posted

技术标签:

【中文标题】使用 Google Apps 脚本设置压缩查询导出【英文标题】:Query Export with Google Apps Script setting compression 【发布时间】:2016-12-08 11:41:21 【问题描述】:

使用 appscript 将大型 (16GB) Biq 查询表导出到 GCS 时,我无法进行压缩。我将压缩类型设置为 GZIP 并将目标格式设置为 NEWLINE_DELIMITED_JSON 但它不压缩文件,而是只输出 116 个文件?

我尝试过extract.compression =extract.setcompression =,但没有任何区别。我该如何解决这个问题?

function extractBigQueryToCloudStorage(compressionType,csFileUri, datasetId, tableId,projectId)  

  //
  var compressionType='GZIP';
  var csFileUri='gs://xxxxxxxxxx/bq_extracts/xxxxxxxxxx.*.JSON';
  var datasetId='xxxxxxxxxx';
  var tableId='xxxxxxxxxx';
  var projectId='xxxxxxxxxx';
  var bqTable = checkBigQueryTable(projectId, datasetId, tableId);

  var fnStart = new Date();

    try 
        var tableReference = BigQuery.newTableReference();
        tableReference.setProjectId(projectId);
        tableReference.setDatasetId(datasetId);
        tableReference.setTableId(tableId);

        var extract = BigQuery.newJobConfigurationExtract()
        extract.setDestinationFormat('NEWLINE_DELIMITED_JSON');
        extract.compression=(compressionType);
        extract.setDestinationUris([csFileUri]);
        extract.setSourceTable(tableReference);

        var configuration = BigQuery.newJobConfiguration();
        configuration.setExtract(extract);
        var newJob = BigQuery.newJob();
        newJob.setConfiguration(configuration);

        var job = BigQuery.Jobs.insert(newJob, projectId);
        var jobId = job.getJobReference().getJobId();    
        var status = job.getStatus();

        while (status.getState() != 'DONE')
            Logger.log(status.getState());
            if(status.getState() == 'PENDING')
                Utilities.sleep(100);
                  
            if (status.getErrorResult() == true)     
                Logger.log('BigQuery file upload error: %s', status.getErrors());
                   
            status = BigQuery.Jobs.get(projectId, jobId).getStatus();
          
     catch(err)  
        Logger.log('BigQuery file upload error: %s', err);  
        return err;   
     
    var fnEnd = new Date();
    Logger.log(status.getState());
    Logger.log('Function loadCloudStorageFileToBigQuery elapsed time: %sms', fnEnd - fnStart);
    Logger.log(status.errorResult);   // check for notification of extract too big (e.g. > 1 Gb)
    return status.getState();


    // Function to determine if a BigQuery table exists. Returns boolean
function checkBigQueryTable(projectId, datasetId, tableId)   
    try  
        var job = BigQuery.Tables.get(projectId, datasetId, tableId);
        return true;
     catch(err)  
        Logger.log('Table %s does not exist' , tableId);    
        return false;   
     

   

【问题讨论】:

【参考方案1】:

你所做的对我来说似乎是正确的。您确定生成的输出不是 GZIP 吗?即使将压缩设置为 GZIP,BigQuery 仍会以 GZIP 格式输出 116 个文件,每个分片一个(使用“.JSON”作为输出 URI 中指示的扩展名)。

我尝试使用 setCompression 使用以下代码,它适用于我:

var tableReference = BigQuery.newTableReference();
tableReference.setProjectId(projectId);
tableReference.setDatasetId(datasetId);
tableReference.setTableId(tableId);

var extract = BigQuery.newJobConfigurationExtract()
extract.setDestinationFormat('NEWLINE_DELIMITED_JSON');
extract.setCompression('GZIP');
extract.setDestinationUris(['gs://xxxxx/output.*.JSON']);
extract.setSourceTable(tableReference);

var configuration = BigQuery.newJobConfiguration();
configuration.setExtract(extract);
var newJob = BigQuery.newJob();
newJob.setConfiguration(configuration);

var job = BigQuery.Jobs.insert(newJob, projectId);
Logger.log("JobId is " + projectId + ":" + jobId);

你可以通过bq command-line client查看你的setCompression是否生效:

bq --format=prettyjson show -j <datasetId>:<jobId>

当它工作时,你应该看到这些行:

...
"extract": 
  "compression": "GZIP", 
  "destinationFormat": "NEWLINE_DELIMITED_JSON", 
...

【讨论】:

以上是关于使用 Google Apps 脚本设置压缩查询导出的主要内容,如果未能解决你的问题,请参考以下文章

Google Apps 脚本:将所有 Google 联系人导出为 CSV

仅在Google Apps脚本中是新文件时才解压缩文件

用于大查询的 Apps 脚本

使用 Apps 脚本对 Google 表格中的边框进行条件格式设置

使用 Google Apps 脚本将查询中的数据加载到 Big Query - 缺少必需参数

是否可以使用 Apps 脚本运行 Google 表格插件?