BigQuery中的任何功能都可以在不执行复制数据的情况下迁移另一个项目中的整个数据集?

时间:2015-09-22 18:56:58

标签: google-bigquery

在我们的项目不断发展的同时,我们意识到我们需要创建新项目并重新组织我们的数据集。一个案例是我们需要将一个数据集与其他数据集隔离到另一个新项目中。我知道我可以通过API逐个复制表然后删除旧表来实现。但是当涉及到超过一千个表时,由于复制api作为一项工作执行而且需要时间,因此它确实消耗了大量时间。是否可以只更改数据集的参考(或路径)?

跟进 我尝试使用批处理请求复制表。我在所有请求中都获得了200 OK,但表格并没有被复制。我想知道为什么以及如何获得真实的结果。这是我的代码:

    public async Task CopyTableToProjectInBatchAsync(IList<TableList.TablesData> fromTables, string toProjectId)
    {
        var request = new BatchRequest(BigQueryService);
        foreach (var tableData in fromTables)
        {
            string fromDataset = tableData.TableReference.DatasetId;
            string fromTableId = tableData.TableReference.TableId;
            Logger.Info("copying table {0}...",tableData.Id);
            request.Queue<JobReference>(CreateTableCopyRequest(fromDataset, fromTableId, toProjectId),
            (content, error, i, message) =>
            {
                Logger.Info("#content:\n" + content);
                Logger.Info("#error:\n" + error);
                Logger.Info("#i:\n" + i);
                Logger.Info("#message:\n" + message);
            });
        }
        await request.ExecuteAsync();
    }

   private IClientServiceRequest CreateTableCopyRequest(string fromDatasetId, string fromTableId, string toProjectId,
        string toDatasetId=null, string toTableId=null)
    {
        if (toDatasetId == null)
            toDatasetId = fromDatasetId;
        if (toTableId == null)
            toTableId = fromTableId;
        TableReference sourceTableReference = new TableReference
        {
            ProjectId = _account.ProjectId,
            DatasetId = fromDatasetId,
            TableId = fromTableId
        };
        TableReference targetTableReference = new TableReference
        {
            ProjectId = toProjectId,
            DatasetId = toDatasetId,
            TableId = toTableId
        };
        JobConfigurationTableCopy copyConfig = new JobConfigurationTableCopy
        {
            CreateDisposition = "WRITE_TRUNCATE",
            DestinationTable = targetTableReference,
            SourceTable = sourceTableReference
        };
        JobReference jobRef = new JobReference {JobId = GenerateJobID("copyTable"), ProjectId = _account.ProjectId};
        JobConfiguration jobConfig = new JobConfiguration {Copy = copyConfig};
        Job job = new Job {Configuration = jobConfig, JobReference = jobRef};

        return BigQueryService.Jobs.Insert(job, _account.ProjectId);
    }

4 个答案:

答案 0 :(得分:6)

没有内置功能,但我帮助编写了一个我们开源的工具,可以为您执行此操作:https://github.com/uswitch/big-replicate

它允许您在项目或数据集之间(在同一项目中)同步/复制表。大部分细节都在项目README中,但供参考,看起来有点像:

java -cp big-replicate-standalone.jar \
  uswitch.big_replicate.sync \
  --source-project source-project-id \
  --source-dataset 98909919 \
  --destination-project destination-project-id \
  --destination-dataset 98909919

您可以设置选项,以控制要复制的表的数量,并发运行的作业数以及在云存储中存储中间数据的位置。目标数据集必须已存在,但这意味着您也可以在位置之间复制数据(美国,欧盟,亚洲等)。

二进制文件构建于CircleCI并发布到GitHub releases

答案 1 :(得分:6)

您可以先将BigQuery数据集复制到新项目,然后再删除原始数据集。

副本数据集UI与副本表相似。只需单击源数据集中的“复制数据集”按钮,然后在弹出表单中指定目标数据集。请参见下面的屏幕截图。查看public documentation,了解更多用例。

复制数据集按钮

enter image description here

复制数据集表格

enter image description here

答案 2 :(得分:5)

一个简短的shell脚本,它将数据集中的所有表复制到另一个数据集:

export SOURCE_DATASET=$1  # project1:dataset
export DEST_PREFIX=$2  # project2:dataset2.any_prefix_
for f in `bq ls $SOURCE_DATASET |grep TABLE | awk '{print $1}'`
do
  export CP_COMMAND="bq cp $SOURCE_DATASET.$f $DEST_PREFIX$f"
  echo $CP_COMMAND
  echo `$CP_COMMAND`
done

答案 3 :(得分:2)

不,目前BigQuery中没有移动或重命名操作。移动数据的最佳方法是复制数据并删除原始数据。

后续回答:您的批处理请求创建了复制作业,但您需要等待它们完成,然后观察结果。您可以使用BigQuery Web UI或从命令行运行“bq ls -j”来查看最近的作业。