更新 BQ 表中 5K 行的高效语法

Posted

技术标签:

【中文标题】更新 BQ 表中 5K 行的高效语法【英文标题】:Efficient syntax to update 5K rows in BQ table 【发布时间】:2021-09-12 16:10:41 【问题描述】:

我正在尝试使用 python 客户端更新 bq 中的约 5K 行。

这是我目前的尝试:

update_bq(table_id=_ADS_TO_REMOVE_TABLE_NAME, set_clasue="status ='removed'",
                                           where_in_clause=f'''[[item['ad_id'] for item in 
                                                                  current_ads_removed_json_chunk]]''')

def update_bq(self, table_id, ad_ids, set_clasue, where_in_clause):
    table_full_name = self.get_table_full_name(table_id)
    query_text = f"""
    UPDATE `table_full_name`
    SET set_clasue
    WHERE account_id IN where_in_clause
    """
    query_job = self.client.query(query_text)

如何将account id list 映射到如下看起来更有效的字符串(?)

UPDATE mytable SET somefield=( CASE WHEN (id=100) THEN 'some value removed' WHEN (id=101) THEN 'some value removed' END ) WHERE id IN (100,101);

我试过了:

f'''UPDATE mytable SET somefield=( CASE  WHEN id=['(id=100) THEN some value \'removed\''.join( item['ad_id'] for item in current_ads_removed_json_chunk]]+"WHERE id IN ("+ item['ad_id'] for item in current_ads_removed_json_chunk]);

另外,bq 自动时间戳会在更新时起作用(在插入时对我起作用)。

删除所有具有这些 ID 的行并重新插入新状态是否更好?

【问题讨论】:

【参考方案1】:

我不知道这是否会更有效,但您可以尝试在 python 中创建整个 sql 脚本。脚本可以包含所有值。值将作为inject_table 传递,然后您可以使用signle 查询更新所有行。

文档:inject table 和 UPDATE FROM

with inject_table (
   select 1 as col1, 2 as col2 UNION ALL
   select 5 as col1, 3 as col2
)
update tt
set tt.val = it.col1
from target_table as tt
join inject_table as it on tt.col2 = it.col2

【讨论】:

以上是关于更新 BQ 表中 5K 行的高效语法的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy中所有行的高效更新

更新大型表上的行的最高效方法

如何向表中插入数据以及如何更新删除表中的数据

更新表中所有行的有效方法

如果表中已经存在行的值,我想更新它

使用其他行的数据更新同一表中的行 SQL