如何在Doobie中创建ClickHouse临时表并添加session_id参数
解决Doobie创建ClickHouse临时表时传递session_id的问题
问题根源
ClickHouse的临时表基于会话(session)隔离,你之前用HC.setClientInfo设置session_id的方式无效——ClickHouse JDBC驱动并不通过JDBC标准的clientInfo传递session_id,必须通过连接URL参数或连接属性来指定。
正确实现方案
方案1:在JDBC连接URL中携带session_id
配置Doobie的Transactor时,直接将session_id拼入连接URL:
import doobie._ import doobie.implicits._ import cats.effect.IO // 构造带session_id的ClickHouse JDBC URL val jdbcUrl = s"jdbc:clickhouse://your-host:8123/your-db?session_id=${sessionId.toString}" val xa = Transactor.fromDriverManager[IO]( "com.clickhouse.jdbc.ClickHouseDriver", jdbcUrl, "your-username", "your-password" ) // 创建临时表的查询(用Doobie的插值语法处理表名,需确保tableName无SQL注入风险) val createTempTable = sql"CREATE TEMPORARY TABLE $tableName (call_id String) ENGINE = Memory" .update .run // 执行创建操作 createTempTable.transact(xa).unsafeRunSync()
方案2:通过连接属性动态传递session_id
如果需要在代码中动态设置session_id,可通过Properties对象传递连接属性:
import java.util.Properties import doobie._ import doobie.implicits._ import cats.effect.IO val props = new Properties() props.setProperty("session_id", sessionId.toString) val xa = Transactor.fromDriverManager[IO]( "com.clickhouse.jdbc.ClickHouseDriver", "jdbc:clickhouse://your-host:8123/your-db", "your-username", "your-password", props // 携带session_id的连接属性 ) // 创建临时表的逻辑同方案1 val createTempTable = sql"CREATE TEMPORARY TABLE $tableName (call_id String) ENGINE = Memory" .update .run createTempTable.transact(xa).unsafeRunSync()
补充说明
- 若你的
tableName是安全可信的(无SQL注入风险),用Doobie的$tableName插值语法比Fragment.const更符合框架规范;如果是不可信的动态值,需额外做安全校验。 - ClickHouse的session_id会绑定整个连接会话,同一Transactor下的所有操作都会共享这个session_id,临时表也只会在该会话生命周期内存在。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

