BigQuery: Как добавить поле в ПОВТОРНУЮ запись? - PullRequest
0 голосов
/ 03 апреля 2020

В Google BigQuery есть таблица, которая состоит из нескольких полей, а затем - ПОВТОРНОЙ записи, которая может содержать один или несколько объектов. Я хочу создать новую таблицу с дополнительным полем в данных REPEATED и скопировать мои исходные данные в новую таблицу, заполнив новое поле выводом GENERATE_UUID (), чтобы в каждой строке данных REPEATED был один уникальный идентификатор.

У меня был похожий вопрос на Как мне скопировать из одной таблицы BigQuery в другую, когда цель содержит поля REPEATED? , но я не знаю, как адаптировать это для моего текущего варианта использования .

Вот моя "новая" Схема 1 (ie Схема 2 по ссылке выше)

[
    {"name": "id", "type": "NUMERIC", "mode": "REQUIRED"},
    {"name": "name", "type": "STRING", "mode": "REQUIRED"},
    {"name": "created", "type": "TIMESTAMP", "mode": "REQUIRED"},
    {"name": "valid", "type": "BOOLEAN", "mode": "REQUIRED"},
    {"name": "parameters", "type": "RECORD", "mode": "REPEATED", "fields":
        [
            {"name": "parameter1", "type": "STRING", "mode": "REQUIRED"},
            {"name": "parameter2", "type": "FLOAT", "mode": "REQUIRED"},
            {"name": "parameter3", "type": "BOOLEAN", "mode": "REQUIRED"}
        ]
    }
]

, и я хотел бы, чтобы это закончилось так, Схема 2:

[
    {"name": "id", "type": "NUMERIC", "mode": "REQUIRED"},
    {"name": "name", "type": "STRING", "mode": "REQUIRED"},
    {"name": "created", "type": "TIMESTAMP", "mode": "REQUIRED"},
    {"name": "valid", "type": "BOOLEAN", "mode": "REQUIRED"},
    {"name": "parameters", "type": "RECORD", "mode": "REPEATED", "fields":
        [
            {"name": "uuid", "type": "STRING", "mode": "REQUIRED"},
            {"name": "parameter1", "type": "STRING", "mode": "REQUIRED"},
            {"name": "parameter2", "type": "FLOAT", "mode": "REQUIRED"},
            {"name": "parameter3", "type": "BOOLEAN", "mode": "REQUIRED"}
        ]
    }
]

Итак, моя новая таблица (таблица 2) создана с использованием этой схемы. Я хочу скопировать из таблицы 1, и я пытаюсь что-то вроде этого:

insert into table2_with_uuid(id, name, created, valid, parameters)
select id, name, created, valid,
[(
GENERATE_UUID(), parameters.parameter1, parameters.parameter2, parameters.parameter3
)]
from table1_no_guid;

Это дает мне сообщение об ошибке: Cannot access field ceId on a value with type ARRAY<STRUCT<parameter1 (et c)

Кто-нибудь есть какие-либо предложения относительно того, как действовать? Спасибо!

Ответы [ 3 ]

1 голос
/ 07 апреля 2020

Я выполнил процедуру в Синтаксис языка манипулирования данными в официальной документации.

Затем, в основном, вы хотите обновить повторяющиеся записи . Я следовал всем примерам, от вставок до обновлений, до того момента, когда второй комментарий был добавлен к повторяющейся записи.

Затем я применил UNNEST-запрос:

insert into `testing.followingDMLmod`  (product, quantity, supply_constrained, comments)
select product, quantity, supply_constrained,
[(
GENERATE_UUID(), com.created, com.comment
)]
from `testing.followingDML` , UNNEST(comments) com;

, который, конечно, работает, но не дает желаемого результата.

Согласно официальной документации "BigQuery изначально поддерживает несколько изменений схемы, таких как добавление нового вложенного поля в запись или ослабление режима вложенного поля." Затем, возможно, путь копирует таблицу, а затем добавляет дополнительное поле.

Это можно сделать после управления схемами таблиц документация . То есть либо с помощью API и вызова tables.patch , что более подробно обсуждалось в этом другом сообщении о переполнении стека, либо с использованием файла JSON со схемой из командная строка.

Я лично следовал второму подходу (JSON файл схемы) и отлично работал для меня. Более подробно шаги, которые я выполнил (см. здесь ):

  • Используйте Copy table в пользовательском интерфейсе BigQuery, чтобы получить копию вашей таблицы без "id" ». Моя стартовая таблица - followDML, а копия --DMLmod.

  • Скопируйте схему из таблицы в файл JSON (здесь он называется myschema. json), выполнив следующую команду в Cloud Shell

bq show \
--schema \
--format=prettyjson \
testing.followingDMLmod > myschema.json
  • Откройте схему в текстовом редакторе. Например, запустив
vim myschema.json
  • Теперь измените схему, чтобы добавить новый вложенный столбец в конец массива полей. (Если вы никогда не использовали vim, очень упрощенным объяснением было бы «es c», чтобы вернуть вас в нормальный режим, а в то время как в обычном режиме нажатие «i» позволяет записывать в открытый файл, «: w» сохраняет file и ": q" выходит из файла) Я включил поле "id":
{
  "mode": "NULLABLE",
  "name": "id",
  "type": "STRING"
}
  • Теперь вам нужно обновить схему, запустив
bq update testing.followingDMLmod myschema.json

Наконец, вернувшись к интерфейсу BigQuery, я использовал запрос

UPDATE `testing.followingDMLmod` 
SET comments = ARRAY(
    SELECT AS STRUCT * REPLACE(GENERATE_UUID() AS id)
    FROM UNNEST(comments)
  )
WHERE true

, чтобы заполнить поле id после создания. После того, что предложено в этом сообщении переполнения стека. Теперь конечный результат действительно соответствует ожиданиям!

0 голосов
/ 06 апреля 2020

Все правильно. И неверно. Гнездо заменяет исходные данные одной строкой на повторяющуюся запись. При попытке выполнить этот запрос:

insert into dummydata_withuuid (id, name, created, valid, parameters)
select id, name, created, valid,
[(
GENERATE_UUID(), parameters.parameter1, parameters.parameter2, parameters.parameter3
)]
from dummydata_nouuid;

показывает ошибку в первом параметре parameters.parameter1, «Не удается получить доступ к полю parameter1 для значения с типом ARRAY> at [5:29]»

Однако, удалите insert into... и измените, как показано ниже, и запрос действителен.

-- insert into dummydata_withuuid (id, name, created, valid, parameters)
select id, name, created, valid,
[(
GENERATE_UUID(), parameters
)]
from dummydata_nouuid;

И я могу сохранить результаты в другой таблице, что является долгим способом получения нужного мне ответа. Что-то, что мне нужно изменить в моей строке insert into..., чтобы сделать запрос действительным?

0 голосов
/ 03 апреля 2020

Мне удалось найти ответ на этот вопрос непосредственно перед публикацией, но я подумал, что другим было бы полезно поделиться этим методом. Вот запрос, который работал:

insert into table2_with_uuid(id, name, created, valid, parameters)
select id, name, created, valid,
[(
GENERATE_UUID(), params.parameter1, params.parameter2, params.parameter3
)]
from table1_no_guid, UNNEST(parameters) params;

Hope this is useful! Please feel free to add to my result or comment to continue the conversation.

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