如何在未知数据格式的前提下从SQLite中加载数据
解决方案
你当前的写法只能统一解析所有列为Text,遇到混合类型的列会解析失败,可按以下方案处理:
用动态类型接收查询结果
主流SQLite Haskell绑定(如sqlite-simple)都提供了通用的动态SQL值类型SQLData,它是一个枚举类型,可覆盖SQLite所有原生数据类型:
SQLInteger:对应SQLite的INTEGER类型,承载HaskellInt64值SQLReal:对应SQLite的REAL类型,承载HaskellDouble值SQLText:对应SQLite的TEXT类型,承载HaskellText值SQLBlob:对应SQLite的BLOB类型,承载HaskellByteString值SQLNull:对应SQLite的NULL值
你可以直接将查询结果的类型声明为[[SQLData]],即可接收任意列类型的返回结果,示例代码如下:
import Database.SQLite.Simple (SQLData(..)) -- 执行查询,返回动态类型的二维集合 (entries :: [[SQLData]]) <- query_ connection "select * from users"
后续你可以通过模式匹配处理不同类型的值,示例处理函数:
import Data.Text (unpack) processSQLValue :: SQLData -> String processSQLValue (SQLInteger i) = "整数: " <> show i processSQLValue (SQLReal r) = "浮点数: " <> show r processSQLValue (SQLText t) = "文本: " <> unpack t processSQLValue (SQLBlob b) = "二进制数据,长度: " <> show (length b) processSQLValue SQLNull = "空值"
提前获取表结构(可选)
如果需要先知道目标表的列名、列类型等元信息,可以查询SQLite内置的table_info pragma获取结构定义:
-- 查询users表的结构信息,返回结果包含列id、列名、列类型、是否非空、默认值、是否主键等字段 (tableInfo :: [(Int, Text, Text, Bool, Maybe SQLData, Bool)]) <- query_ connection "PRAGMA table_info(users)"
拿到表结构后你可以根据列类型做针对性的解析逻辑。
自定义解析(可选)
如果后续你总结出了固定的类型组合规则,也可以自定义实现FromRow类型类的实例,实现更高效的自定义解析逻辑,适合部分固定结构的场景。
内容的提问来源于stack exchange,提问作者adius
相关产品推荐
相关产品推荐

