从其他表复制数据时的BigQuery架构更新

时间:2019-06-25 14:33:32

标签: google-bigquery

我有table1,其中有很多嵌套列。并且table2还有一些其他列,这些列可能具有嵌套列。我正在使用golang客户端库。

从一个表复制到另一个表时,有什么方法可以更新架构??

示例代码:

dataset := client.Dataset("test")
copier=dataset.Table(table1).CopierFrom(dataset.Table(table2))
copier.WriteDisposition = bigquery.WriteAppend
copier.CreateDisposition = bigquery.CreateIfNeeded
job, err = copier.Run(ctx)
    if err != nil {
        fmt.Println("error while run :", err)
    }
    status, err = job.Wait(ctx)
    if err != nil {
        fmt.Println("error in wait :", err)
    }
    if err := status.Err(); err != nil {
        fmt.Println("error in status :", err)
    }

1 个答案:

答案 0 :(得分:0)


首先了解背景信息: 我在数据集合test下创建了2个表,如下所示:
1模式:名称(字符串),年龄(整数)

"Varun", 19
"Raja", 27

2模式pet_name(字符串),键入(字符串)

"jimmy", "dog"
"ramesh", "cat"

请注意,两个关系具有不同的架构。 在这里,我将数据表2的内容复制到1中。 bigquery.WriteAppend告诉查询引擎将表2的结果附加到1中。

test := client.Dataset("test")
copier := test.Table("1").CopierFrom(test.Table("2"))
copier.WriteDisposition = bigquery.WriteAppend
if _, err := copier.Run(ctx); err != nil {
    log.Fatalln(err)
}
query := client.Query("SELECT * FROM `test.1`;")
results, err := query.Read(ctx)
if err != nil {
   log.Fatalln(err)
}
for {
    row := make(map[string]bigquery.Value)
    err := results.Next(&row)
    if err == iterator.Done {
        return
    }
    if err != nil {
        log.Fatalln(err)
    }
    fmt.Println(row)
}

什么也没有发生,结果是:

map[age:19 name:Varun]
map[name:Raja age:27]

1中,目标未更改。 如果源和目标副本中具有相同的架构怎么办? 例如:

copier := test.Table("1").CopierFrom(test.Table("1"))

然后复制成功!添加表1的行数是最初的两倍。

map[name:Varun age:19]
map[age:27 name:Raja]
map[name:Varun age:19]
map[name:Raja age:27]

但是,如果我们想以某种方式组合表甚至具有不同模式怎么办?

首先,您在技术上正在执行数据处理(DML)时需要一个GCP结算帐户。您可以获得$ 300的免费信用额。

然后以下内容将起作用

query := client.Query("SELECT * FROM `test.2`;")
query.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION", "ALLOW_FIELD_RELAXATION"}
query.CreateDisposition = bigquery.CreateIfNeeded
query.WriteDisposition = bigquery.WriteAppend
query.QueryConfig.Dst = client.Dataset("test").Table("1")
results, err := query.Read(ctx)

结果是

map[pet_name:<nil> type:<nil> name:Varun age:19]
map[name:Raja age:27 pet_name:<nil> type:<nil>]
map[pet_name:ramesh type:cat name:<nil> age:<nil>]
map[pet_name:jimmy type:dog name:<nil> age:<nil>]

编辑

如果您只想运行查询而不回取结果,则可以使用query.Read()代替query.Run(),如下所示:

if _, err := query.Run(ctx); err != nil {
    log.Fatalln(err)
}

要注意的重要事项:

  • 我们已将query.SchemaUpdateOptions设置为包括ALLOW_FIELD_ADDITION,这将使结果表具有最初不存在的列。
  • 我们已将query.WriteDisposition设置为bigquery.WriteAppend,以便附加数据。
  • 我们已将query.QueryConfig.Dst设置为client.Dataset("test").Table("1"),这意味着查询结果将上传到1
  • 不在两个表中但仅在一个表中的值被 nullified 或在Golang意义上设置为nil

hack 将为您提供与合并两个表相同的结果。

希望这会有所帮助。