【问题标题】:How to omit column values when doing a bulk-insert slick 3.x?执行批量插入 slick 3.x 时如何省略列值?
【发布时间】:2016-06-05 12:47:25
【问题描述】:

我有一个 JOURNAL 表,其中 INSERT_DATE 列应由数据库填充插入记录时的当前日期和时间。我没有故意使用 TIMESTAMP 类型,因为它的范围有限。

class Journal(tag: Tag) extends Table[JournalEntry](tag, "JOURNAL") { 
   def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
   def insertDate = column[OffsetDateTime]("INSERT_DATE", SqlType("DateTime default CURRENT_TIMESTAMP"))(localDateTimeColumnType)
   def valueDate = column[OffsetDateTime]("VALUE_DATE", SqlType("DateTime"))(localDateTimeColumnType)
   def amount = column[Int]("AMOUNT")
   def note = column[String]("NOTE", O.Length(100))

   def * : ProvenShape[JournalEntry] = (id.?, insertDate.?, valueDate, amount, note) 
     <> ((JournalEntry.apply _).tupled, JournalEntry.unapply)
}

我还实现了一个案例类:

case class JournalEntry(id: Option[Int], insertDate: Option[LocalDateTime], 
  valueDate: LocalDateTime, amount: Int, note: String)

当我的应用启动时,我用随机测试数据填充数据库:

TableQuery[Journal] ++= Seq.fill(1000)(JournalEntry(None, Some(LocalDateTime.now()), 
   LocalDateTime.of(2006 + Random.nextInt(10), 1 + Random.nextInt(11), 
   1 + Random.nextInt(27),Random.nextInt(24), Random.nextInt(60)), Random.nextInt(),
   TestDatabase.randomString(100)))

这可行,但 INSERT_DATE 是由 JVM 设置的,而不是由数据库设置的。 Slick 文档说,如果想要插入默认值,则应该省略列。但是如果我有一个案例类,我就是不明白我是如何省略列的。

我还发现了这个SO post,但不知道如何在我的上下文中使用它。

有什么想法吗?

【问题讨论】:

    标签: scala slick-3.0


    【解决方案1】:

    Slick 文档在第一个代码 sn-p here 中给出了这种省略的示例。按照步骤或the cvogt's answer,您将得到解决方案:

    TableQuery[Journal].map(je =&gt; (je.id, je.valueDate, je.amount, je.note)) ++= Seq.fill(1000)((None, LocalDateTime.of(2006 + Random.nextInt(10), 1 + Random.nextInt(11), 1 + Random.nextInt(27),Random.nextInt(24), Random.nextInt(60)), Random.nextInt(), TestDatabase.randomString(100)))

    【讨论】:

    • 对我不起作用:[error] Slick does not know how to map the given types. [error] Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List). [error] Required level: slick.lifted.FlatShapeLevel [error] Source type: (slick.lifted.Rep[Int], slick.lifted.Rep[java.time.LocalDateTime], slick.lifted.Rep[Int], slick.lifted.Rep[String]) [error] Unpacked type: T [error] Packed type: G [error] TableQuery[Journal].map(je =&gt; (je.id, je.valueDate, je.amount, je.note)) ++=
    【解决方案2】:

    我的工作方式如下:

    import java.time.{ ZonedDateTime, ZoneOffset}
    import slick.profile.SqlProfile.ColumnOption.SqlType
    import scala.concurrent.duration.Duration
    import scala.concurrent.Await
    
    implicit val zonedDateTimeType = MappedColumnType.base[ZonedDateTime, Timestamp](
        {dt =>Timestamp.from(dt.toInstant)},
        {ts =>ZonedDateTime.ofInstant(ts.toInstant, ZoneOffset.UTC)}
    )
    
    class Users(tag: Tag) extends Table[(String, ZonedDateTime)](tag, "users") {
        def name = column[String]("name")
        def createAt = column[ZonedDateTime]("create_at", SqlType("timestamp not null default CURRENT_TIMESTAMP"))
        def * = (name, createAt)
    }
    
    val users = TableQuery[Users]
    val setup = DBIO.seq(
        users.schema.create,
        users.map(u => (u.name)) ++= Seq(("Amy"), ("Bob"), ("Chris"), ("Dave"))
    Await.result(db.run(setup), Duration.Inf)
    

    我在这里没有使用案例类,只是一个元组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-07
      相关资源
      最近更新 更多