2016-06-05 8 views
5

Ho una tabella JOURNAL in cui la colonna INSERT_DATE deve essere compilata dal DB con la data e l'ora correnti quando il record è inserito. Non ho usato il tipo TIMESTAMP di proposito, a causa della sua gamma limitata.Come omettere i valori delle colonne quando si esegue una 3.x intersezione di massa?

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) 
} 

Ho anche implementare una classe caso:

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

Quando la mia applicazione si avvia, io popolo DB con i dati di test casuale:

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))) 

questo funziona, ma l'ist INSERT_DATE impostato dalla JVM non dal Database. I documenti Slick dicono che le colonne dovrebbero essere omesse, se si vuole che il valore predefinito venga inserito. Ma non capisco come ometto le colonne se ho una case class.

Ho trovato anche questo SO post ma non riuscivo a capire come usarlo nel mio contesto.

Qualche idea?

risposta

2

I documenti Slick forniscono un esempio di tale omissione nel primo snippet di codice here. Seguire i passaggi o the cvogt's answer e si arriva alla soluzione:

TableQuery[Journal].map(je => (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)))

+0

Non funziona per me: '[errore] Slick non sa come mappare i tipi specificati. [errore] Possibili cause: T nella tabella [T] non corrisponde alla proiezione *. Oppure usi un tipo non supportato in una Query (ad esempio Scala List). [errore] Livello richiesto: slick.lifted.FlatShapeLevel [errore] Tipo di origine: (slick.lifted.Rep [Int], slick.lifted.Rep [java.time.LocalDateTime], slick.lifted.Rep [Int] , slick.lifted.Rep [String]) [errore] Tipo non imballato: T [errore] Tipo di imballaggio: G [errore] TableQuery [Journal] .map (je => (je.id, je.valueDate, je .amount, je.note)) ++ = ' – binford

1

Io lavoro nel modo seguente:

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) 

non sto usando classe caso qui, solo una tupla.

Problemi correlati