You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何去除ClickHouse参数化查询中默认添加的单引号

解决ClickHouse参数化查询中标识符被添加单引号的问题

你遇到的问题根源在于substitute_params方法的设计定位:它是专门为SQL值参数提供的注入防护机制,会自动为参数添加单引号,但库名、表名这类属于SQL标识符,不能用这种方式处理。

要在避免单引号的同时防范SQL注入,推荐以下方法:

使用quote_identifier安全转义标识符

clickhouse_driver提供了quote_identifier方法,专门用于安全转义SQL标识符(库、表、列名等),它会用ClickHouse支持的反引号包裹标识符,并正确转义内部的特殊字符,既保证SQL语法正确,又能防范注入风险。

示例代码:

from clickhouse_driver import Client

c = Client(host="localhost")
db_name = "test"
table_name = "t"

# 安全转义标识符
quoted_db = c.quote_identifier(db_name)
quoted_table = c.quote_identifier(table_name)

# 拼接查询语句
query = f"SELECT * FROM {quoted_db}.{quoted_table}"
print(query)

执行后输出的SQL为:

SELECT * FROM `test`.`t`

ClickHouse完全支持反引号包裹的标识符,不会出现语法错误,同时即使传入带有特殊字符的标识符(比如包含空格、单引号或恶意注入内容),quote_identifier也会正确转义,避免执行恶意SQL。

为什么不能用substitute_params处理标识符

substitute_params的核心逻辑是把参数当作SQL值处理,所以会自动添加单引号,这就导致原本的标识符被转换成了字符串常量,触发SQL语法错误。比如你示例中生成的SELECT * from 'test'.'t',ClickHouse会把'test'和't'当作字符串,而不是库表名,自然无法正确执行。

绝对不要直接拼接未转义的标识符

如果直接用f-string拼接原始的库表名(比如f"SELECT * FROM {db_name}.{table_name}"),当传入的标识符包含恶意内容时(比如db_name = "test'; DROP TABLE users; --"),就会直接执行恶意SQL,造成数据泄露或破坏,必须用quote_identifier做安全转义。

内容的提问来源于stack exchange,提问作者Odess4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:20:42