如何使用Anorm将JSON插入Postgres表中?

问题描述 投票:0回答:1

[尝试在JSON列中插入JSON字符串时遇到运行时异常。我的字符串看起来像"""{"Events": []}""",表中的列定义为status JSONB NOT NULL。我可以从命令行将字符串插入表中没问题。我已经定义了一种方法来进行插入:

    import play.api.libs.json._
    import anorm._
    import anorm.postgresql._

    def createStatus(
      status: String,
      created: LocalDateTime = LocalDateTime.now())(implicit c: SQLConnection): Unit = {
      SQL(s"""
             |INSERT INTO status_feed
             |  (status, created)
             |VALUES
             |  ({status}, {created})
             |""".stripMargin)
        .on(
          'status -> Json.parse("{}"), // n.b. would be Json.parse(status) but this provides a concise error message
          'created -> created)
        .execute()
    }

并且调用它会出现以下错误:

TypeDoesNotMatch(Cannot convert {}: org.postgresql.util.PGobject to String for column ColumnName(status_feed.status,Some(status)))
anorm.AnormException: TypeDoesNotMatch(Cannot convert {}: org.postgresql.util.PGobject to String for column ColumnName(status_feed.status,Some(status)))

我已经完成了大量搜索此问题的工作,但是我找不到这个特定用例的任何东西-大多数情况是将json列拉入case类。我已经尝试过使用Spray-json的JsValue,播放的JsValue稍有不同的格式,只需按原样传递字符串并使用::JSONB强制将其强制转换为查询,它们都会给出相同的错误。

更新:这是创建表的SQL:

  CREATE TABLE status_feed (
    id SERIAL PRIMARY KEY,
    status JSONB NOT NULL,
    created TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW()
  )
postgresql scala anorm spray-json play-json
1个回答
0
投票

错误不是在给.executeInsert的值上,而是在对INSERT结果(插入键)的解析上。

import java.sql._

// postgres=# CREATE TABLE test(foo JSONB NOT NULL);

val jdbcUrl = "jdbc:postgresql://localhost:32769/postgres"
val props = new java.util.Properties()
props.setProperty("user", "postgres")
props.setProperty("password", "mysecretpassword")

implicit val con = DriverManager.getConnection(jdbcUrl, props)

import anorm._, postgresql._
import play.api.libs.json._

SQL"""INSERT INTO test(foo) VALUES(${Json.obj("foo" -> 1)})""".
  executeInsert(SqlParser.scalar[JsValue].singleOpt)

// Option[play.api.libs.json.JsValue] = Some({"foo":1})

/*
postgres=# SELECT * FROM test ;
    foo     
------------
 {"foo": 1}
 */

顺便说一句,纯字符串插值是没有用的。

© www.soinside.com 2019 - 2024. All rights reserved.