【问题标题】:BigQuery Schema Update while copying data from other tablesBigQuery 架构更新,同时从其他表复制数据
【发布时间】:2019-07-02 18:16:28
【问题描述】:

我有 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)
    }

【问题讨论】:

  • 您好。您能否提供有关您的问题的更多信息以及您想要实现的目标? TBH 这里没有太多信息可供参考。
  • 嗨@Graham Polley,添加示例代码供您参考。

标签: google-bigquery


【解决方案1】:


先介绍一下背景:
我在数据集合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 将给您带来与合并两个表格相同的结果。

希望这会有所帮助。

【讨论】:

  • 我也试过这个。查询会将数据带到我们的环境中。取而代之的是,我需要一个简单的语句由 bigquery end 完成。
  • @ArulRulzz 您能否澄清一下此处采用的方法如何将数据带入您的环境?没有数据保存到您的本地计算机。一切都在 GCP 上完成。
  • 已根据您的要求更新@ArulRulzz
  • 这很有帮助。谢谢
猜你喜欢
  • 2017-07-12
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多