原因
使用clickhouse-driver插入数据时,clickhouse-driver会校验字段的格式和表里定义的是否一致
上源码
https://github.com/mymarilyn/clickhouse-driver/blob/master/clickhouse_driver/client.py#L315
原理
使用clickhouse-driver insert数据常规的方法如下:
from clickhouse_driver import Client
client = Client(host='host', database='database')
insert_sql = 'insert into your_table values'
datas = [[1,2,3], [4,5,6]]
client.execute(insert_sql, datas)
调用client.execute
时传入的两个字段分别对应源码中execute方法里的query、params
参数。
看下注释中对params
的定义:
简述:params作为insert的数据时,传入的数据类型应该为list
, tuple
或~types.GeneratorType
这三种。
源码中可以看到,判断执行的sql是不是insert操作的方法也是判断params
的数据类型。因此,一个简单的绕过数据验证的方法就是不使用params
将要insert的数据传入。我们可以直接将要insert的数据拼接到sql里,params
不传入数据,这样Client就会将insert sql认成一个普通的查询sql来执行。
具体的方法
from clickhouse_driver import Client
client = Client(host='host', database='database')
datas = [[1,2,3], [4,5,6]]
values = ', '.join(map(lambda d: str(tuple(map(str, d))), datas))
insert_sql = 'insert into your_table values %s' % values
client.execute(insert_sql)
要注意的地方
- clickhouse默认是不限制sql长度的,但如果你要一次插入的数据过多(比如10w+),可能要验证一下数据是否全部插入了
- 如果你的数据中有特殊字符,如英文的单引号,可能需要对数据特殊处理一下