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

使用Kotlin Dataframe读取SQLite时Integer转Boolean抛出类型转换异常

解决Kotlin Dataframe读取SQLite布尔列时的ClassCastException问题

问题背景

SQLite无原生Boolean类型,以1/0存储布尔值。使用Kotlin Dataframe读取包含这类列的表时,抛出类型转换异常:

java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Boolean (java.lang.Integer and java.lang.Boolean are in module java.base of loader 'bootstrap')
at Cell In[0], line 13

执行脚本:

USE {
    dependencies("org.xerial:sqlite-jdbc:3.47.1.0")
}

%use kandy
%use dataframe

val connection = DriverManager.getConnection("jdbc:sqlite:../data/data.db")
val repositories = DataFrame.readSqlTable(connection, "Repositories")
println(repositories.columnNames())
println(repositories.columnTypes())
println(repositories[3].is_disabled)

输出显示列类型被推断为kotlin.Boolean,但实际JDBC返回的是Integer值,导致强制转换失败:

[id, name, size, project_id, default_branch, is_disabled]
[kotlin.String, kotlin.String, kotlin.Long, kotlin.String?, kotlin.String?, kotlin.Boolean]

java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Boolean (java.lang.Integer and java.lang.Boolean are in module java.base of loader 'bootstrap')
at Cell In[0], line 13

Exposed可正常解析,说明不是数据本身问题,而是Dataframe默认读取逻辑未适配SQLite的布尔存储规则。

原因分析

  • SQLite JDBC驱动将存储的1/0以Integer类型返回,但Kotlin Dataframe在自动推断列类型时,误将对应列识别为Boolean,直接执行强制类型转换引发异常。
  • Exposed内部针对SQLite做了适配,自动将Integer类型的1/0转换为Boolean值,而Dataframe默认SQL读取逻辑没有处理这种特定场景。

解决方案

1. 读取后手动转换列类型

读取数据后,将Integer类型的列转换为Boolean(支持可空列):

// 非空布尔列
val repositories = DataFrame.readSqlTable(connection, "Repositories")
    .convert<Int>("is_disabled") { it == 1 }

// 可空布尔列
val repositories = DataFrame.readSqlTable(connection, "Repositories")
    .convert<Int?>("is_disabled") { it?.let { it == 1 } }

2. 配置JDBC连接强制返回Boolean类型

通过连接属性配置SQLite驱动,让其将1/0以Boolean类型返回:

import java.util.Properties

val props = Properties()
// 告诉SQLite驱动将对应列按Boolean类型处理
props.setProperty("sqlite.jdbc.booleanType", "BOOLEAN")
val connection = DriverManager.getConnection("jdbc:sqlite:../data/data.db", props)
val repositories = DataFrame.readSqlTable(connection, "Repositories")

注:该配置需要xerial sqlite-jdbc 3.30.0及以上版本支持。

3. 显式指定列类型读取

使用readSqlTable的重载方法,手动指定列的目标类型,避免自动推断错误:

// 非空布尔列
val repositories = DataFrame.readSqlTable(
    connection,
    "Repositories",
    columnTypes = mapOf("is_disabled" to Boolean::class)
)

// 可空布尔列
val repositories = DataFrame.readSqlTable(
    connection,
    "Repositories",
    columnTypes = mapOf("is_disabled" to Boolean?::class)
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:55:18