将数据上传到表,而无需等待流缓冲区刷新

时间:2019-01-12 21:20:27

标签: go google-bigquery

我有一个Go程序,该程序从表(T1)下载数据,对其进行格式化,然后将其上传到新的临时表(T2)。数据上传后(大约30秒钟),应将数据复制到第三张表(T3)。

将格式化的数据上载到T2之后,查询表将返回确定结果。但是,复制表时-作业几乎立即完成,目标表(T3)为空。

我正在按照建议的here复制表格-但是在用户界面中执行操作时的结果是相同的。

在表元数据部分中,其显示为0B,0行,但其中大约有10万行和18mb的数据-或至少是从查询中得到的结果。

编辑,我没有发现此数据仍停留在流缓冲区中-请参阅我的答案。

1 个答案:

答案 0 :(得分:0)

关于我的问题的评论使我看到问题是流缓冲。这需要花费很长时间进行冲洗-无法手动冲洗。

我最终阅读了此问题,并在GitHub here上发表了评论。建议改用加载作业。

经过研究,我意识到可以通过配置加载程序的io.Reader来读取ReaderSource和Google Cloud Storage参考。

我使用流缓冲区的原始实现如下所示:

var vss []*bigquery.ValuesSaver
// for each row:
vss = append(vss, &bigquery.ValuesSaver{
    Schema:   schema,
    InsertID: fmt.Sprintf(index of loop),
    Row: []bigquery.Value{
        "data"
    },
})

err := uploader.Put(ctx, vss)
if err != nil {
    if pmErr, ok := err.(bigquery.PutMultiError); ok {
        for _, rowInsertionError := range pmErr {
            log.Println(rowInsertionError.Errors)
        }
    }

    return fmt.Errorf("failed to insert data: %v", err)
}

我能够使用如下代码将其更改为加载作业:

var lines []string
for _, v := range rows {
    json, err := json.Marshal(v)
    if err != nil {
        return fmt.Errorf("failed generate json %v, %+v", err, v)
    }
    lines = append(lines, string(json))
}

dataString := strings.Join(lines, "\n")

rs := bigquery.NewReaderSource(strings.NewReader(dataString))
rs.FileConfig.SourceFormat = bigquery.JSON
rs.FileConfig.Schema = schema
loader := dataset.Table(t2Name).LoaderFrom(rs)
loader.CreateDisposition = bigquery.CreateIfNeeded
loader.WriteDisposition = bigquery.WriteTruncate
job, err := loader.Run(ctx)
if err != nil {
    return fmt.Errorf("failed to start load job %v", err)
}
_, err := job.Wait(ctx)
if err != nil {
    return fmt.Errorf("load job failed %v", err)
}

现在表中的数据立即可用-我不再需要等待流缓冲区。