在 Slick 中,如何为 Table 提供默认列

Posted

技术标签:

【中文标题】在 Slick 中,如何为 Table 提供默认列【英文标题】:In Slick, how to provide default columns for Table 【发布时间】:2015-09-04 11:35:32 【问题描述】:

我的所有表都共享一些列,因此我想为所有表提供默认列。以下是我到目前为止所尝试的。我正在使用 Slick 3.0。

// created_at and updated_at are the columns every table share
abstract class BaseTable[T](tag: Tag, tableName: String) 
     extends Table[T](tag, tableName) 

  def currentWhenInserting = new Timestamp((new Date).getTime)

  def createdAt = column[Timestamp]("created_at", O.Default(currentWhenInserting))

  def updatedAt = column[Timestamp]("updated_at", O.Default(currentWhenInserting))


实现这一点的简单方法如下所示。

case class Student(
  name: String, age: Int, 
  created_at: Timestamp, updated_at: Timestamp
)

class Students(tag: Tag) extends BaseTable[Student](tag, "students")

  def name = column[String]("name")
  def age = column[Int]("age")

  override def * : ProvenShape[Student] = 
        (name, age, createdAt, updatedAt).shaped <> 
        (Student.tupled, Student.unapply _)

但这是不可取的。

首先,强制每个表行案例类包含 created_at 和 updated_at。如果我有更多从 API 设计角度完全无法接受的字段。

其次,在(name, age, createdAt, updatedAt)中明确写出两个createdAt, updatedAt。这不是我对默认行的期望。

我理想的解决方法如下:

case class Student(name: String, age: Int)

class Students(tag: Tag) extends BaseTable[Student](tag, "students")    

  def name = column[String]("name")
  def age = column[Int]("age")

  override def * : ProvenShape[Student] = 
        (name, age).shaped <> 
        (Student.tupled, Student.unapply _)

在BaseTable或Define BaseCaseClass中编写一些方法,以避免在表定义中显式编写额外的两个字段,如Student和行案例类定义Student。

不过,经过一番痛苦的挣扎,还是可以做到的。 任何帮助将不胜感激。

【问题讨论】:

开始可能是让Student 扩展一个具有createdAtupdatedAt 的基础对象。不确定您是否可以以某种方式使用它来使* 不那么冗长。只提出想法 - 不是 Scala/Slick 专家。 【参考方案1】:

我正在使用以下模式:

case class Common(arg0: String, arg1: String)

trait Commons  this: Table[_] =>
  def arg0 = column[String]("ARG0", O.Length(123))
  def arg1 = column[String]("ARG1", O.Length(123))

  def common = (arg0, arg1).<> [Meta, (String, String)](
    r => 
      val (arg0, arg1) = r
      Meta(arg0, arg1)
    ,
    o => Some(o.arg0, o.arg1)
  )


case class MyRecord(a: String, b: String, common: Common)

class MyRecords(tag: Tag) extends Table[MyRecord](tag, "MY_RECORDS") with Commons 
  def a = column[String]("A", O.PrimaryKey, O.Length(123))
  def b = column[String]("B", O.Length(123))

  def * = (a, b, common) <> (MyRecord.tupled, MyRecord.unapply)

它并不完美,但它有助于避免重复,而不是难以理解。

【讨论】:

以上是关于在 Slick 中,如何为 Table 提供默认列的主要内容,如果未能解决你的问题,请参考以下文章

在 Scala Spark 中,当源列为 NULL 时如何为派生列添加默认值?

在winform中,如何为DatagridView设置横向滚动条

Bigquery API:如何为 load_table_from_storage 调用提供架构

如何为不同的方法选择特定的列?

在Postgres中加入两个表后如何为具有相同名称的列提供别名

如何为网站的主要部分提供 2 列布局以使其看起来不错?