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

时间:2018-01-09 21:57:19

标签: google-bigquery

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

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

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

4 个答案:

答案 0 :(得分:11)

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

  

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

<强> TABLE_DATA
enter image description here

<强> table_changes
enter image description here

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

更新查询:

#standardSQL
UPDATE `yourproject.yourdadtaset.table_data` t
SET t.value = s.value
FROM `yourproject.yourdadtaset.table_changes` s
WHERE t.id = s.id

结果将是
enter image description here

现在 - 插入查询

#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`)

结果为(我们在这里完成)
enter image description here

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

答案 1 :(得分:9)

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

在BQ中无法按事务表中的知道更新行。每个表每天只有100个更新。这非常有限,他们的目的完全不同。

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

查看后面的大多数问题:BigQuery - DELETE statement to remove duplicates

答案 2 :(得分:8)

BigQuery现在支持MERGE,它可以在一个原子操作(即INSERT)中结合使用UPDATEUPSERT

使用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)

enter image description here

请参见here

答案 3 :(得分:3)

为此,我可能迟到了,但是您可以使用Dataflow / Apache Beam在BigQuery中执行upsert。您可以执行CoGroupByKey以从两个数据源(一个是目标表)中获取共享公用密钥的值,并更新从目标BQ表中读取的数据。最后以截断加载模式加载数据。希望这会有所帮助。

这样,您可以避免BigQuery中的所有配额限制,并在Dataflow中进行所有更新。