如何使用 Slick 在 Postgres 中将 json 对象插入到 jsonb 类型的列中

Posted

技术标签:

【中文标题】如何使用 Slick 在 Postgres 中将 json 对象插入到 jsonb 类型的列中【英文标题】:How to Insert a json object to a column of type jsonb in Postgres using Slick 【发布时间】:2021-12-22 11:51:30 【问题描述】:

我正在尝试使用 Slick 将 json 对象插入到 Postgres 中 jsonb 类型的列中。这是我迄今为止尝试过的..

implicit val attributesJsonFormat = jsonFormat1(Attribute)

implicit val attributesJsonMapper = MappedColumnType.base[Attribute, String](
     attribute => attribute.toJson.toString() ,
     column => column.parseJson.convertTo[Attribute] 
  )
属性案例类..
case class Attribute(randomVal: Int)
在这里,我期望 Slick 在读取和写入之间进行隐式转换。但相反,我收到以下错误..
列 \"attributes\" 是 jsonb 类型,但表达式是字符变化类型\n 提示:您需要重写或强制转换表达式

我认为发生此错误是因为 Slick 尝试将对象保存为 varchar。 然后我创建了一个触发器,它将在插入或更新之前调用一个函数。这个函数的作用是在保存到数据库之前将相关对象转换为jsonb。

CREATE OR REPLACE FUNCTION parse_attributes_to_json_in_accounts()
    RETURNS TRIGGER AS
$$
BEGIN
    NEW.attributes = to_jsonb(NEW.attributes);
    RETURN NEW;
END;
$$
    LANGUAGE plpgsql;


CREATE TRIGGER tr_parse_attributes_to_json
    BEFORE INSERT OR UPDATE
    ON accounts
    FOR EACH ROW
EXECUTE PROCEDURE parse_attributes_to_json_in_accounts();


ALTER FUNCTION parse_attributes_to_json_in_accounts() OWNER TO app;

即使在此解决方案之后,我仍然会收到相同的错误消息。我猜 Slick 在达到这一点之前就抛出了异常?有什么想法可以让它工作吗?

【问题讨论】:

【参考方案1】:

有一个库为许多不同的 PostgreSQL 类型添加了 Slick 支持: https://github.com/tminglei/slick-pg

【讨论】:

在不使用第三方库的情况下有什么变通办法吗? 当然,你可以复制他们的源代码。但是你为什么要这样做呢? 公司对第三方依赖有严格的政策.. 寻找另一家公司。【参考方案2】:

对于遇到类似问题的任何人,您可以使用原生 sql 和 jsonb 转换。

sqlu"INSERT INTO accounts VALUES ($account.id, (to_jsonb($jsonAttribute) #>> '')::jsonb)"

执行上述查询会在属性列中插入一条带有 jsonb 对象的新记录。

更多信息可以在这里找到.. https://scala-slick.org/doc/3.0.0/sql.html

【讨论】:

以上是关于如何使用 Slick 在 Postgres 中将 json 对象插入到 jsonb 类型的列中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 slick 3.0 中将 Rep[T] 转换为 T?

如何在 react-slick 中将类添加到 li 标签

是否有使用 Postgres 的 Slick 2.0 AutoInc 的工作示例?

Play2/Specs2 中的 Slick/Postgres 数据库测试问题

在 slick、scala 中处理 Postgres json 数据类型

Slick 3 - 如何在使用纯 SQL 插入时获得正确的(数据库)架构