你如何在 Scala Slick 中运行补丁/部分数据库更新? [英] How do you run a patch/partial database UPDATE in Scala Slick?

查看:56
本文介绍了你如何在 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 期望元组长度和类型与 filterupdate 函数的结果相匹配.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆