У нас есть гигантская таблица, и нам нужно добавить к ней столбец type
.
Технически столбец должен быть ненулевым, но миграция обновления всего (150M записей) немного сумасшедшая.
Поэтому мы решили оставить его обнуляемым и встроить преобразователь прямо в синтаксический анализатор, чтобы модель всегда заполнялась правильным значением, а когда данные сохраняются, медленно, но верно, данные будут заполняться.
Этот подход работает для нас во многих местах для обнуляемого логического значения.
Моя модель выглядит так:
package models.tasks
import anorm.{Column, _}
import db.ProcessStreetColumn._
import exceptions.ProcessStreetException
import json.ProcessStreetJoda
import models._
import models.checklists.ChecklistRevision
import models.organization.Organization
import models.task_templates.TaskTemplate
import org.joda.time.DateTime
import play.api.libs.json.{Format, Json}
import st.process.util.Muid
case class Task(id: Muid,
audit: AuditMetadata,
completedDate: Option[DateTime],
completedBy: Option[Ref[User]],
organization: Ref[Organization],
taskTemplate: Ref[TaskTemplate],
checklistRevision: Ref[ChecklistRevision],
status: Task.Status.Value,
dueDate: Option[DateTime],
dueDateOverridden: Boolean,
hidden: Boolean,
stopped: Boolean,
taskType: Task.TaskType.Value)
extends Identifiable[Muid]
with Auditable
object Task extends ProcessStreetModel[Task] with ProcessStreetJoda {
object TaskType extends Enumeration with AnormEnumeration with JsonEnumeration {
val Standard, Approval = Value
}
...
Для этого случая я создал этот конвертер:
val nullableRowToTaskType: Column[TaskType.Value] = Column[TaskType.Value] {
case (value, MetaDataItem(qualified, _, _)) =>
Option(value) match {
case Some(TaskType.Approval) => Right(TaskType.Approval)
case Some(TaskType.Standard) | None => Right(TaskType.Standard)
case _ =>
Left(TypeDoesNotMatch("Cannot convert " + value + " to TaskType for column " + qualified))
}
}
И я использую его следующим образом:
...
SqlParser.get[TaskType.Value](qualifiedColumnNameOf(prefix, "task_type"))(nullableRowToTaskType)
...
Но в конвертере я получаю следующую ошибку:
play.sbt.PlayExceptions$CompilationException: Compilation error[object Column does not take type parameters.]
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:34)
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:34)
at scala.Option.map(Option.scala:146)
at play.sbt.run.PlayReload$.$anonfun$taskFailureHandler$1(PlayReload.scala:33)
at scala.Option.map(Option.scala:146)
at play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:28)
at play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:24)
at play.sbt.run.PlayReload$.$anonfun$compile$3(PlayReload.scala:51)
at scala.util.Either$LeftProjection.map(Either.scala:573)
at play.sbt.run.PlayReload$.compile(PlayReload.scala:51)
Я не совсем уверен, что с этим делать ... Не уверен, что это значит.
Что я делаю не так?