Обновление схемы BigQuery при копировании данных из других таблиц - PullRequest
0 голосов
/ 25 июня 2019

У меня есть table1, в котором много вложенных столбцов.И таблица2 имеет несколько дополнительных столбцов, которые могут иметь вложенные столбцы.Я использую клиентскую библиотеку 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 голосов
/ 01 июля 2019


Сначала немного фона:
Я создал 2 таблицы под сбором данных test следующим образом:
1 Схема: имя (строка), возраст (целое число)

"Varun", 19
"Raja", 27

2 Схема pet_name (String), тип (String)

"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>]

EDIT

Вместо 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.
  • Значения, которые находятся не в обеих таблицах, а только в одной, обнуляются или имеют значение nil в смысле Голанга.

Этот хак даст вам те же результаты, что и объединение двух таблиц.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...