使用clickhouse-driver插入数据时触发ValueError:参数需为字典格式
问题诊断
你遇到的这个问题是clickhouse-driver 0.1.4版本的一个已知逻辑缺陷。虽然官方文档声称INSERT支持生成器作为数据输入,但这个版本的execute方法在处理请求时,并没有正确区分「INSERT的数据」和「SELECT的参数」:
看你贴的源码,process_ordinary_query方法直接调用了substitute_params,而这个方法粗暴地检查params是否为dict,只要不是就抛出错误——完全没考虑INSERT场景下传入生成器/列表的情况。
解决方案
有两种可行的解决办法,根据你的实际情况选择:
1. 升级clickhouse-driver到新版本(推荐)
这个问题在后续的版本(比如0.2.0及以上)中已经被修复:新版本的execute方法会先判断当前查询是否是INSERT语句,如果是,就会把params当作插入数据处理,不会走到substitute_params的逻辑里。
执行升级命令:
pip install --upgrade clickhouse-driver
2. 临时兼容:将生成器转为列表(不推荐大数据集)
如果因为环境限制无法升级,可以在调用execute前把生成器转换成列表,因为列表是旧版本支持的输入类型:
修改你的insert_data函数:
def insert_data(data: Iterable[Dict], table: str, client: Client = None): columns = get_table_cols(table) client = client or get_ch_client(0) query = f"insert into {table} ({', '.join(columns)}) values" data = map(lambda row: {key: row[key] for key in columns}, data) # 把生成器转为列表,适配旧版本driver client.execute(query, list(data))
注意:这种方式会把所有数据加载到内存中,如果你的数据集很大,可能会引发内存问题,所以优先推荐升级版本。
内容的提问来源于stack exchange,提问作者go2nirvana
相关产品推荐
相关产品推荐

