#python-3.x #pandas #google-bigquery
# #python-3.x #pandas #google-bigquery
Вопрос:
Я загружаю данные из фреймов данных pandas в BigQuery, используя пакет pandas-gbq:
df.to_gbq('dataset.table', project_id, reauth=False, if_exists='append')
Типичный фрейм данных выглядит так:
key | value | order
"sd3e" | 0.3 | 1
"sd3e" | 0.2 | 2
"sd4r" | 0.1 | 1
"sd4r" | 0.5 | 2
Есть ли способ отклонить попытку загрузки, если ключ уже отображается в таблице BigQuery?
Ответ №1:
Есть ли способ отклонить попытку загрузки, если ключ уже отображается в таблице BigQuery?
Нет, поскольку BigQuery не поддерживает ключи аналогично другим базам данных. Для решения этой проблемы существует 2 типичных варианта использования:
Вариант 1:
Загрузите данные с меткой времени и используйте команду слияния для удаления дубликатов
Смотрите Эту ссылку о том, как это сделать, это пример
MERGE `DATA` AS target
USING `DATA` AS source
ON target.key = source.key
WHEN MATCHED AND target.ts < source.ts THEN
DELETE
Примечание: В этом случае вы платите за сканирование слиянием, но сохраняете уникальность строки таблицы.
Вариант 2:
Загрузите данные с меткой времени и используйте ROW_NUMBER
функцию window для извлечения последней записи, это пример с вашими данными:
WITH DATA AS (
SELECT 'sd3e' AS key, 0.3 as value, 1 as r_order, '2019-04-14 00:00:00' as ts UNION ALL
SELECT 'sd3e' AS key, 0.2 as value, 2 as r_order, '2019-04-14 01:00:00' as ts UNION ALL
SELECT 'sd4r' AS key, 0.1 as value, 1 as r_order, '2019-04-14 00:00:00' as ts UNION ALL
SELECT 'sd4r' AS key, 0.5 as value, 2 as r_order, '2019-04-14 01:00:00' as ts
)
SELECT *
FROM (
SELECT * ,ROW_NUMBER() OVER(PARTITION BY key order by ts DESC) rn
FROM `DATA`
)
WHERE rn = 1
Это приводит к ожидаемым результатам следующим образом:
Примечание: В этом случае дополнительные расходы не взимаются, однако вы всегда должны обязательно использовать функцию window при извлечении из таблицы
Комментарии:
1. спасибо за ваш быстрый ответ !… Мне удалось удалить дубликаты, следуя вашим предложениям .. хотя, поскольку ответ на мой вопрос «нет», я думаю, что вместо этого я буду использовать метод pandas duplicated() ..