如何在ClickHouse中为已有key的Array(String)添加元素且不新增行
问题描述
我刚开始学习ClickHouse,使用Python的clickhouse_connect库,无法实现向Array(String)类型字段中添加新字符串。我的代码如下:
import clickhouse_connect ch_client = clickhouse_connect.get_client(host=ch_host, user=ch_user, password=ch_pass, database=ch_datebase) ch_client.command(f'CREATE TABLE IF NOT EXISTS {ch_table} (key String, strings Array(String)) ENGINE MergeTree ORDER BY key') insert_data = [['123', ['string1']]] ch_client.insert(ch_table, insert_data, column_names=['key', 'strings']) insert_data = [['123', ['string2']]] ch_client.insert(ch_table, insert_data, column_names=['key', 'strings'])
需求:当key已存在时,向对应数组中添加元素;当key不存在时,新增一行数据。
解决方案
直接利用ClickHouse的INSERT ... ON DUPLICATE KEY UPDATE语法,配合arrayConcat函数即可实现需求,无需额外判断key是否存在。
1. 确认表结构有效性
你的表已将key设为ORDER BY字段,MergeTree引擎默认将ORDER BY字段作为主键,满足唯一性校验要求,无需修改表结构。
2. 修改插入逻辑
在clickhouse_connect的insert方法中,通过on_duplicate_key参数指定更新规则:
import clickhouse_connect ch_client = clickhouse_connect.get_client(host=ch_host, user=ch_user, password=ch_pass, database=ch_datebase) ch_client.command(f'CREATE TABLE IF NOT EXISTS {ch_table} (key String, strings Array(String)) ENGINE MergeTree ORDER BY key') # 首次插入:key不存在则新增行 insert_data = [['123', ['string1']]] ch_client.insert( ch_table, insert_data, column_names=['key', 'strings'], on_duplicate_key='strings = arrayConcat(strings, values(strings))' ) # 二次插入:key已存在则合并数组 insert_data = [['123', ['string2']]] ch_client.insert( ch_table, insert_data, column_names=['key', 'strings'], on_duplicate_key='strings = arrayConcat(strings, values(strings))' )
补充说明
values(strings)指代本次插入操作中的新数组值- 如果需要避免数组中出现重复元素,可将
arrayConcat替换为arrayUnion:strings = arrayUnion(strings, values(strings))
内容的提问来源于stack exchange,提问作者Artem Solov'yev
相关产品推荐
相关产品推荐

