你如何在 Scala Slick 中运行补丁/部分数据库更新? [英] How do you run a patch/partial database UPDATE in Scala Slick?
问题描述
我们想使用 Slick (3.0.0) 运行补丁/部分 UPDATE
以便我们只修改记录中的某些字段.究竟哪些字段将被准确更新,只有在运行时才能知道.
We'd like to run a patch/partial UPDATE
with Slick (3.0.0) so that we only modify some of the fields in a record. Exactly which fields will be updated exactly will only be known at runtime.
例如,对于 REST PATCH
请求.
For example, for a REST PATCH
request.
目前我们先运行 SELECT
来获取原始记录,然后运行 UPDATE
但最好在单个 SQL 语句中执行此操作.
Currently we run a SELECT
first to get the original record then run an UPDATE
but it would be nicer to do this in a single SQL statement.
像这样:
def patchPerson(name: Option[String], age: Option[Int]) = {
people.filter(_.name === "M Odersky")
.map(p =>
(name, age) match {
case (Some(_), Some(_)) => (p.name, p.age)
case (Some(_), None) => (p.name)
case (None , Some(_)) => (p.age)
}
)
.update(
(name, age) match {
case (Some(_), Some(_)) => (name.get, age.get)
case (Some(_), None) => (name.get)
case (None , Some(_)) => (age.get)
}
)
}
(请忽略这里丑陋的代码)
以上不编译并显示以下错误消息:
The above does not compile with the following error message:
未找到匹配的形状.Slick 不知道如何映射给定的类型.可能的原因:表[T]中的T与您的*不匹配投影.或者您在查询中使用了不受支持的类型(例如 scala列表).所需级别:slick.lifted.FlatShapeLevel 源类型:对象解包类型:T 打包类型:G
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. Or you use an unsupported type in a Query (e.g. scala List). Required level: slick.lifted.FlatShapeLevel Source type: Object Unpacked type: T Packed type: G
还有:
方法映射的参数不足:(隐式形状:slick.lifted.Shape[_ <: slick.lifted.FlatShapeLevel, Object, T,G])slick.lifted.Query[G,T,Seq].未指定值参数形状.
not enough arguments for method map: (implicit shape: slick.lifted.Shape[_ <: slick.lifted.FlatShapeLevel, Object, T, G])slick.lifted.Query[G,T,Seq]. Unspecified value parameter shape.
我认为这是因为 Slick 期望元组长度和类型与 filter
和 update
函数的结果相匹配.
I assume this is because Slick expects the tuple length and type to match the results for both the filter
and update
functions.
我们已经尝试使用 Slick 异构列表 类,但这似乎也期望长度和类型匹配.
We've tried using the Slick heterogeneous list class but this also seems to expect the length and types to match.
有没有办法在 Slick 中编写它,以便我们可以通过一次数据库调用更新记录中任意数量的字段?
Is there a way to write this in Slick so that we can update an arbitrary number of fields in a record with one database call?
推荐答案
为什么不在构造更新查询之前进行模式匹配?
Why not do the pattern matching before constructing the update query?
def patchPerson(name: Option[String], age: Option[Int]) = {
val query = people.filter(_.name === "M Odersky")
(name, age) match {
case (Some(name), Some(age)) =>
query.map(p => (p.name, p.age)).update(name, age)
case (Some(name), None) =>
query.map(p => p.name).update(name)
case (None, Some(age)) =>
query.map(p => p.age).update(age)
}
}
这篇关于你如何在 Scala Slick 中运行补丁/部分数据库更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!