Попытка создать преобразователь null-to-enum, встроенный в парсер - PullRequest
0 голосов
/ 17 мая 2019

У нас есть гигантская таблица, и нам нужно добавить к ней столбец 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)

Я не совсем уверен, что с этим делать ... Не уверен, что это значит. Что я делаю не так?

...