Google BQ - 如何在表格中存储现有数据?

Ale*_*oev 7 google-bigquery

我正在使用Python客户端库在BigQuery表中加载数据.我需要更新这些表中的一些更改的行.但我无法弄清楚如何正确更新它们?我想要一些类似的UPSERT功能 - 只有在不存在时插入行,否则 - 更新现有行.

这是在表中使用带校验和的特殊字段(并在加载过程中比较总和)的正确方法吗?如果有一个好主意,如何用Python客户端解决这个问题?(据我所知,它无法更新现有数据)

请解释一下,最佳做法是什么?

Gra*_*ley 17

BigQuery现在支持MERGE,它可以结合一个INSERTUPDATE一个原子操作,即UPSERT.

使用Mikhail的示例表,它看起来像:

MERGE merge_example.table_data T
USING merge_example.table_changes S
ON T.id = S.id
WHEN MATCHED THEN
  UPDATE SET value = s.value
WHEN NOT MATCHED THEN
  INSERT (id, value) VALUES(id, value)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

看到这里.

  • 这看起来很棒,但是如果一个表是 csv 或 python(数据框),这是否可以做到。或者您是否需要在 BigQuery 中创建另一个临时表,然后合并这两个表? (5认同)

Mik*_*ant 12

BigQuery不UPSERT直接支持,但如果你真的需要它 - 你可以使用UPDATEINSERT一个接一个地实现相同.见下面简化的例子

假设您有两个表,如下所示 - 一个用于保存数据(yourproject.yourdadtaset.table_data),另一个yourproject.yourdadtaset.table_changes用于包含要应用于第一个表的更改

TABLE_DATA
在此输入图像描述

table_changes
在此输入图像描述

现在,下面的查询一个接一个地执行操作:

更新查询:

#standardSQL
UPDATE `yourproject.yourdadtaset.table_data` t
SET t.value = s.value
FROM `yourproject.yourdadtaset.table_changes` s
WHERE t.id = s.id
Run Code Online (Sandbox Code Playgroud)

结果将是
在此输入图像描述

现在 - 插入查询

#standardSQL
INSERT `yourproject.yourdadtaset.table_data` (id, value)
SELECT id, value
FROM `yourproject.yourdadtaset.table_changes`
WHERE NOT id IN (SELECT id FROM `yourproject.yourdadtaset.table_data`)
Run Code Online (Sandbox Code Playgroud)

结果为(我们在这里完成)
在此输入图像描述

希望上面的例子简单明了,所以你可以在你的情况下应用它


Pen*_*m10 10

BigQuery是设计附加的首选.这意味着您最好从表中的同一实体中获取重复行,并将查询写入以始终读取最近的行.

如BQ中所述,无法在事务表中更新行.每个表每天只有100个更新.这是非常有限的,他们的目的是完全不同的.

由于BQ用作数据湖,因此您应该在每次用户时流式传输新行,例如:更新其个人资料.您将最终为同一用户提供20行20行.稍后,您可以通过删除重复数据将表重新打造为具有唯一行.

请参阅后面的大多数问题:BigQuery - DELETE语句以删除重复项

  • 这不再准确,不应该是公认的答案。BigQuery 现在允许对表进行无限制的 DML 操作。https://cloud.google.com/bigquery/quotas#standard_tables (7认同)