先介绍一下背景:
我在数据集合test 下创建了 2 个表,如下所示:
1 Schema: name (String), age (Integer)
"Varun", 19
"Raja", 27
2 Schema 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]
但是,如果我们想以某种方式合并表,甚至具有不同的架构,该怎么办?
首先,您需要一个 GCP 结算帐户,因为您在技术上是在进行数据操作 (DML)。您可以获得 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.Run() 而不是query.Read(),如下所示:
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。
- 不在两个表中但仅在一个表中的值被无效或在 Golang 中设置为
nil。
这个 hack 将给您带来与合并两个表格相同的结果。
希望这会有所帮助。