BigQuery-使用goLang获取1000000条记录并对数据进行一些处理

时间:2019-05-22 03:04:09

标签: database go google-bigquery

我在BigQuery中有1000000条记录。从数据库中获取数据并使用goLang处理的最佳方法是什么?如果无限制地获取所有数据,则会出现超时问题。我已经将限制增加到5分钟,但是需要超过5分钟。 我想执行一些流式呼叫或分页实现,但是我不知道golang中的方法。

var FetchCustomerRecords = func(req *http.Request) *bigquery.RowIterator {
    ctx := appengine.NewContext(req)
    ctxWithDeadline, _ := context.WithTimeout(ctx, 5*time.Minute)
    log.Infof(ctx, "Fetch Customer records from BigQuery")
    client, err := bigquery.NewClient(ctxWithDeadline, "ddddd-crm")
    q := client.Query(
        "SELECT * FROM Something")

    q.Location = "US"
    job, err := q.Run(ctx)
    if err != nil {
        log.Infof(ctx, "%v", err)
    }
    status, err := job.Wait(ctx)
    if err != nil {
        log.Infof(ctx, "%v", err)

    }
    if err := status.Err(); err != nil {
        log.Infof(ctx, "%v", err)
    }
    it, err := job.Read(ctx)

    if err != nil {
        log.Infof(ctx, "%v", err)
    }
    return it
}

2 个答案:

答案 0 :(得分:2)

您可以直接读取表内容,而无需发出查询。这不会产生查询费用,并且提供与从查询中获得的相同的行迭代器。

对于小的结果,这很好。对于大型表,我建议您检出新的storage apisamples page上的代码示例。

对于小型表或仅读取行的一小部分,您可以执行以下操作(从一个公共数据集表中读取多达1万行):

func TestTableRead(t *testing.T) {
    ctx := context.Background()
    client, err := bigquery.NewClient(ctx, "my-project-id")
    if err != nil {
        t.Fatal(err)
    }

    table := client.DatasetInProject("bigquery-public-data", "stackoverflow").Table("badges")
    it := table.Read(ctx)

    rowLimit := 10000
    var rowsRead int
    for {
        var row []bigquery.Value
        err := it.Next(&row)
        if err == iterator.Done || rowsRead >= rowLimit {
            break
        }

        if err != nil {
            t.Fatalf("error reading row offset %d: %v", rowsRead, err)
        }
        rowsRead++
        fmt.Println(row)
    }
}

答案 1 :(得分:1)

您可以拆分查询以获取100000条记录的10倍并在多个goroutine中运行

像这样使用sql查询  select * from somewhere order by id DESC limit 100000 offset 0

以及下一个goroutine select * from somewhere order by id DESC limit 100000 offset 100000