如何使用Slick向PostgreSQL的jsonb类型字段插入JSON对象
问题根本原因
你定义的MappedColumnType默认将Attribute类型映射为JDBC的字符串类型,Slick生成SQL时会将该字段标记为varchar类型,PostgreSQL执行SQL前会先做参数类型校验,发现varchar与目标jsonb字段类型不匹配直接抛出错误,该校验发生在触发器执行之前,因此触发器方案不会生效。
解决方法
方案1:自定义带jsonb类型标记的列映射(推荐)
无需额外依赖,只需修改你的隐式映射逻辑,显式指定该列在数据库层面的类型为jsonb即可:
import slick.jdbc.PostgresProfile.api._ import spray.json._ implicit val attributesJsonFormat = jsonFormat1(Attribute) implicit val attributesJsonMapper = MappedColumnType.base[Attribute, String]( { attribute => attribute.toJson.compactPrint }, { column => column.parseJson.convertTo[Attribute] }, // 显式指定数据库列类型为jsonb,替换默认的varchar映射 SqlType("jsonb") )
同时在表结构定义时,也可以给对应列加上类型约束,避免后续歧义:
class Accounts(tag: Tag) extends Table[Account](tag, "accounts") { // 其他字段省略 def attributes = column[Attribute]("attributes", O.SqlType("jsonb")) // 其他字段省略 }
方案2:SQL层面手动添加类型强转
如果临时需要快速验证,也可以在插入/更新语句中手动给字段添加::jsonb强转标记:
// 插入语句示例 sqlu"INSERT INTO accounts (id, attributes) VALUES ($id, ${Attribute(123).toJson.compactPrint}::jsonb)"
注意:触发器方案无需继续使用,类型校验阶段的错误无法通过触发器解决。
内容的提问来源于stack exchange,提问作者Poorna
相关产品推荐
相关产品推荐

