如何在 slick 3.2.0 中将 Map[String, String] 映射到 (String, String)
How to map Map[String, String] to (String, String) in slick 3.2.0
我正在尝试更新我的 Postgres table 中的 hstore 字段。它抛出一个错误
Error:(468, 13) No matching Shape found.
Slick does not know how to map the given types.
Possible causes: T in Table[T] does not match your * projection,
you use an unsupported type in a Query (e.g. scala List),
or you forgot to import a driver api into scope.
Required level: slick.lifted.FlatShapeLevel
Source type: slick.lifted.Rep[Option[scala.collection.immutable.Map[String,String]]]
Unpacked type: T
Packed type: G
.map(_.additionalInfo).update(Some(info.additionalInfo))
我也添加了 hstore implicit
trait MyPostgresDriver extends ExPostgresProfile with PgHStoreSupport {
override val api = MyAPI
// Add back `capabilities.insertOrUpdate` to enable native `upsert` support; for postgres 9.5+
override protected def computeCapabilities: Set[Capability] =
super.computeCapabilities + JdbcProfile.capabilities.insertOrUpdate
object MyAPI extends API with HStoreImplicits
}
浏览后我发现可以为此类场景创建自定义映射。
implicit val stringMapper = MappedColumnType.base[Map[String, String], (String, String)](
list => (list.keys.toString(), list.values.toString()),
string => Map(string._1 -> string._2)
)
但是上面的自定义映射不正确。我找到了这个 blog
但它隐含在版本 3.x
中不存在
我们将不胜感激。
尝试
import com.github.tminglei.slickpg._
trait MyPostgresProfile extends ExPostgresProfile
with PgArraySupport
with PgHStoreSupport {
override val api = MyAPI
object MyAPI extends API
with ArrayImplicits
with HStoreImplicits {
implicit val strListTypeMapper = new SimpleArrayJdbcType[String]("text").to(_.toList)
}
}
object MyPostgresProfile extends MyPostgresProfile
import MyPostgresProfile.api._
case class Student(
id: Int,
name: String,
hobbies: List[String],
marks: Map[String, String])
class StudentTable(tag: Tag) extends Table[Student](tag, "student") {
def id = column[Int]("id", O.PrimaryKey)
def name = column[String]("name")
def hobbies = column[List[String]]("hobbies", O.Default(Nil))
def marks = column[Map[String, String]]("marks")
def * = (id, name, hobbies, marks) <> (Student.tupled, Student.unapply)
}
lazy val studentQuery: TableQuery[StudentTable] = TableQuery[StudentTable]
val db = Database.forURL("jdbc:postgresql://localhost:5432/student", "root", "root",
null, "org.postgresql.Driver")
val student = Student(1, "Ayush", List("Study", "Coding"), Map("Scala" -> "90", "Java" -> "80", "PHP" -> "0"))
db.run {
studentQuery += student
}
build.sbt
lazy val slickV = "3.3.2"
//lazy val slickV = "3.2.0"
libraryDependencies ++= Seq(
"com.typesafe.slick" %% "slick" % slickV,
"org.slf4j" % "slf4j-nop" % "1.7.28",
"com.typesafe.slick" %% "slick-hikaricp" % slickV,
"com.github.tminglei" %% "slick-pg" % "0.18.0"
)
根据错误,缺少 slick implicit,这有助于您将 Map[String, String]
用作 PgHStore
。您需要在代码块的范围内添加 (implicit a: JdbcType[Map[String, String]])
。我猜这是 HStoreImplicits
或 PgHStoreSupport
提供的。
我正在尝试更新我的 Postgres table 中的 hstore 字段。它抛出一个错误
Error:(468, 13) No matching Shape found.
Slick does not know how to map the given types.
Possible causes: T in Table[T] does not match your * projection,
you use an unsupported type in a Query (e.g. scala List),
or you forgot to import a driver api into scope.
Required level: slick.lifted.FlatShapeLevel
Source type: slick.lifted.Rep[Option[scala.collection.immutable.Map[String,String]]]
Unpacked type: T
Packed type: G
.map(_.additionalInfo).update(Some(info.additionalInfo))
我也添加了 hstore implicit
trait MyPostgresDriver extends ExPostgresProfile with PgHStoreSupport {
override val api = MyAPI
// Add back `capabilities.insertOrUpdate` to enable native `upsert` support; for postgres 9.5+
override protected def computeCapabilities: Set[Capability] =
super.computeCapabilities + JdbcProfile.capabilities.insertOrUpdate
object MyAPI extends API with HStoreImplicits
}
浏览后我发现可以为此类场景创建自定义映射。
implicit val stringMapper = MappedColumnType.base[Map[String, String], (String, String)](
list => (list.keys.toString(), list.values.toString()),
string => Map(string._1 -> string._2)
)
但是上面的自定义映射不正确。我找到了这个 blog 但它隐含在版本 3.x
中不存在我们将不胜感激。
尝试
import com.github.tminglei.slickpg._
trait MyPostgresProfile extends ExPostgresProfile
with PgArraySupport
with PgHStoreSupport {
override val api = MyAPI
object MyAPI extends API
with ArrayImplicits
with HStoreImplicits {
implicit val strListTypeMapper = new SimpleArrayJdbcType[String]("text").to(_.toList)
}
}
object MyPostgresProfile extends MyPostgresProfile
import MyPostgresProfile.api._
case class Student(
id: Int,
name: String,
hobbies: List[String],
marks: Map[String, String])
class StudentTable(tag: Tag) extends Table[Student](tag, "student") {
def id = column[Int]("id", O.PrimaryKey)
def name = column[String]("name")
def hobbies = column[List[String]]("hobbies", O.Default(Nil))
def marks = column[Map[String, String]]("marks")
def * = (id, name, hobbies, marks) <> (Student.tupled, Student.unapply)
}
lazy val studentQuery: TableQuery[StudentTable] = TableQuery[StudentTable]
val db = Database.forURL("jdbc:postgresql://localhost:5432/student", "root", "root",
null, "org.postgresql.Driver")
val student = Student(1, "Ayush", List("Study", "Coding"), Map("Scala" -> "90", "Java" -> "80", "PHP" -> "0"))
db.run {
studentQuery += student
}
build.sbt
lazy val slickV = "3.3.2"
//lazy val slickV = "3.2.0"
libraryDependencies ++= Seq(
"com.typesafe.slick" %% "slick" % slickV,
"org.slf4j" % "slf4j-nop" % "1.7.28",
"com.typesafe.slick" %% "slick-hikaricp" % slickV,
"com.github.tminglei" %% "slick-pg" % "0.18.0"
)
根据错误,缺少 slick implicit,这有助于您将 Map[String, String]
用作 PgHStore
。您需要在代码块的范围内添加 (implicit a: JdbcType[Map[String, String]])
。我猜这是 HStoreImplicits
或 PgHStoreSupport
提供的。