首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala平滑插入表,省略某些列并返回新行的主键

Scala平滑插入表,省略某些列并返回新行的主键
EN

Stack Overflow用户
提问于 2021-03-17 04:11:23
回答 1查看 144关注 0票数 0

对于scala项目,我使用play-slickplay-slick-evolutions两个版本的5.0.0,并且我使用slick-codegen版本的3.3.3生成我的db类。

我有一个表,其中包含一个primary key列和一些包含default values的列。我想插入一行,但没有提到主键列,也没有任何具有默认值的列。理想情况下,此操作应返回已创建行的新主键。

我的问题是,从slick-codegen生成的代码似乎只允许插入整行,因为它为行使用了自己的case类。生成的代码如下所示(不带注释):

代码语言:javascript
复制
case class SalesOrderRow(idSalesOrder: Int, fkCustomer: Int, createdAt: java.sql.Timestamp, createdBy: Option[String] = None)

implicit def GetResultSalesOrderRow(implicit e0: GR[Int], e1: GR[java.sql.Timestamp], e2: GR[Option[String]]): GR[SalesOrderRow] = GR{
  prs => import prs._
  SalesOrderRow.tupled((<<[Int], <<[Int], <<[java.sql.Timestamp], <<?[String]))
}

class SalesOrder(_tableTag: Tag) extends profile.api.Table[SalesOrderRow](_tableTag, Some("test"), "sales_order") {
  def * = (idSalesOrder, fkCustomer, createdAt, createdBy) <> (SalesOrderRow.tupled, SalesOrderRow.unapply)
  def ? = ((Rep.Some(idSalesOrder), Rep.Some(fkCustomer), Rep.Some(createdAt), createdBy)).shaped.<>({r=>import r._; _1.map(_=> SalesOrderRow.tupled((_1.get, _2.get, _3.get, _4)))}, (_:Any) =>  throw new Exception("Inserting into ? projection not supported."))

  val idSalesOrder: Rep[Int] = column[Int]("id_sales_order", O.AutoInc, O.PrimaryKey)
  val fkCustomer: Rep[Int] = column[Int]("fk_customer")
  val createdAt: Rep[java.sql.Timestamp] = column[java.sql.Timestamp]("created_at")
  val createdBy: Rep[Option[String]] = column[Option[String]]("created_by", O.Length(20,varying=true), O.Default(None))
}

lazy val SalesOrder = new TableQuery(tag => new SalesOrder(tag))

有了这段生成的代码,我现在可以插入一行并提到完整的列:

代码语言:javascript
复制
val insertActionsNotSoNice =
  DBIO.seq(
    salesOrders += Tables.SalesOrderRow(0, 3, new Timestamp(System.currentTimeMillis()), Some("这个不好"))
  )

但我想省略开头的主键和具有默认值的时间戳参数。但不能做这样的事。

代码语言:javascript
复制
val insertActionsNotCompiling =
  DBIO.seq(
    salesOrders.map(so => (so.fkCustomer, so.createdBy) += (3, Some("这个好")))
  )

我在slick文档和web中发现了许多类似后一种方法的示例,但它们用于数据库的类确实有一个元组,而不是自己的row类。比如..。

代码语言:javascript
复制
class Coffees(tag: Tag) extends Table[(String, Int, Double, Int, Int)](tag, "COFFEES")

而不是

代码语言:javascript
复制
class Coffees(_tableTag: Tag) extends profile.api.Table[CoffeesRow](_tableTag, Some("test"), "coffee")

我是不是必须把slick-codegen从我的项目中去掉,然后自己编写所有的类来满足我的需求,或者我用play-slick组合的库是不是错了?或者,在插入未记录的内容时,是否有一个简单的技巧可以省略列?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-21 18:49:42

经过几天的尝试,我找到了一个解决方案。

您可以在查询上进行映射,以便只选择要安装的列,然后如果希望返回插入行的id,则可以使用returning

代码语言:javascript
复制
import dao.Tables.profile.api._

// ...

val salesOrders = TableQuery[SalesOrder]
val insertStatement = salesOrders.map(so => (so.fkCustomer, so.createdBy)) returning salesOrders.map(_.idSalesOrder) into ((_, id) => id)

然后,您可以编写类似以下内容:

代码语言:javascript
复制
val newSalesOrderIdFuture = db.run(insertStatement += (5, Some("有效")))

因此,我在insert语句中省略了主键列(id_sales_order)和在数据库中缺省为now()的时间戳列(created_at)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66662688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档