BigQuery - Удалить строки из секционированной таблицы

У меня есть дневная таблица на BigQuery. Когда я пытаюсь удалить некоторые строки из таблицы, используя запрос вроде:

DELETE FROM `MY_DATASET.partitioned_table` WHERE id = 2374180

Я получаю следующую ошибку:

Ошибка: операторы DML еще не поддерживаются для секционированных таблиц.

Быстрый поиск в Google приводит меня к: https://cloud.google.com/bigquery/docs/loading-data-sql-dml где также говорится: "Операторы DML, которые изменяют многораздельные таблицы, еще не поддерживаются".

Итак, пока есть ли обходной путь, который мы можем использовать при удалении строк из многораздельной таблицы?

3 ответа

Решение

DML имеет некоторые известные проблемы/ ограничения на этом этапе.

Такие как:

  • Операторы DML нельзя использовать для изменения таблиц с ОБЯЗАТЕЛЬНЫМИ полями в их схеме.
  • Каждый оператор DML инициирует неявную транзакцию, что означает, что изменения, внесенные этим оператором, автоматически фиксируются в конце каждого успешного оператора DML. Нет поддержки транзакций с несколькими выписками.
  • Следующие комбинации операторов DML могут выполняться одновременно в таблице: UPDATE и INSERT
    УДАЛИТЬ и ВСТАВИТЬ
    ВСТАВИТЬ и ВСТАВИТЬ
    В противном случае одно из операторов DML будет прервано. Например, если два оператора UPDATE выполняются одновременно с таблицей, то только один из них будет успешным.
  • Таблицы, которые были недавно записаны с помощью BigQuery Streaming (tabledata.insertall), не могут быть изменены с помощью операторов UPDATE или DELETE. Чтобы проверить, есть ли в таблице потоковый буфер, проверьте ответ tables.get для раздела с именем streamingBuffer. Если она отсутствует, таблицу можно изменить с помощью операторов UPDATE или DELETE.
  • Операторы DML, которые изменяют многораздельные таблицы, пока не поддерживаются.

Также будьте в курсе ограничений квоты

  • Максимальное количество операторов UPDATE/DELETE в день на одну таблицу: 48
  • Максимальное количество обновлений / удалений в день на проект: 500
  • Максимальное количество операторов INSERT в день на одну таблицу: 1000
  • Максимальное количество вставок в день на проект: 10 000

Что вы можете сделать, это скопировать весь раздел в однораздельную таблицу и выполнить там инструкцию DML. Чем записать временную таблицу в раздел. Кроме того, если вы сталкивались с инструкциями ограничения обновлений DML в день для каждой таблицы, вам нужно создать копию таблицы и запустить DML для новой таблицы, чтобы избежать ограничения.

Вы можете удалить разделы в многораздельных таблицах с помощью командной строки bq rm, как это:

bq rm 'mydataset.mytable$20160301'

Я уже сделал это без временной таблицы, шаги:

1) подготовить запрос, который выбирает все строки из определенного раздела, которые должны быть сохранены:

SELECT * FROM `your_data_set.tablename` WHERE 
_PARTITIONTIME = timestamp('2017-12-07') 
AND condition_to_keep_rows_which_shouldn't_be_deleted = 'condition' 

при необходимости запустите это для других разделов

2) выберите таблицу назначения для результата вашего запроса, где вы указываете на ОСОБЕННОЕ РАЗДЕЛЕНИЕ, вам необходимо указать имя таблицы следующим образом:

tablename$20171207

3) Отметьте опцию "Перезаписать таблицу" -> она будет перезаписывать только определенный раздел

4) Запустите Query, в результате из указанного раздела лишние строки будут удалены!

// помните, что вам может потребоваться запустить это для других разделов, где удаляемые строки распределены по нескольким разделам

Похоже, на момент написания статьи это больше не ограничение BigQuery!

В стандартном SQL оператор, подобный приведенному выше, для многораздельной таблицы будет успешным при условии, что удаляемые строки не были недавно (в течение последних 30 минут) вставлены через потоковую вставку.

Текущие документы по DML: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-manipulation-language

Пример запроса, который работал у меня в пользовательском интерфейсе BQ:

DELETE 
FROM dataset_name.partitioned_table_on_timestamp_column
WHERE 
timestamp >= '2020-02-01' AND timestamp < '2020-06-01'

После того, как хомяки покрутятся, получаем ответ BQ:

This statement removed 101 rows from partitioned_table_on_timestamp_column
Другие вопросы по тегам