具有超过 22 个字段的 Playframework 和 Scala Slick 元组

Playframework and Scala Slick tuple with more than 22 fields

我的案例 class 大约有 26 个数据库字段,但在 Scala 和/或 Scala Slick 中有限制为 22 个字段。

有没有办法打破这个限制?

我试过这个:

没有什么好结果^^

提前致谢。

更新:

我尝试了这个例子,但出现了错误...

我的代码如下所示:

package dto.regulations.models

import ai.x.play.json.Jsonx
import dto.client.models.{PriceCategoriesModel, SlaLevelsModel}
import dto.crawler.models.{CrawlerModel, CrawlerUrlsModel, ResultsCrawlerModel}
import play.api.db.slick.HasDatabaseConfigProvider
import play.api.libs.json._
import slick.jdbc.JdbcProfile
import slick.lifted.ProvenShape

import slick.jdbc.H2Profile.api._
import shapeless._
import slickless._

case class RegulationModel(
                            regulationId: Option[Int] = None,
                            name: String,
                            [.... some other attributes....]
                            // Non Database fields
                            priceCategory: Option[PriceCategoriesModel]  = None,
                            slaLevel: Option[SlaLevelsModel]  = None,

                            markets: Option[Seq[MarketsModel]] = None,
                            tags: Option[Seq[TagsModel]]  = None,
                            crawler: Option[CrawlerModel]  = None,
                            commentCreatedAt: Option[String]  = None,
                            creatorComment: Option[String]  = None,
                            approved: Option[Boolean]  = None,
                            approverComment: Option[String],
                            approvedAt: Option[String],
                            creatorUuid: Option[String],
                            approverUuid: Option[String],

                            regulationPackages: Option[Seq[RegulationPackagesModel]],
                            regulation_Evaluations: Option[Seq[Regulation_EvaluationModel]]
                          ) {
  def toApi: RegulationApi = RegulationApi.fromModel(this)
}


object RegulationModel {
  implicit val regulationFormat: OFormat[RegulationModel] = Jsonx.formatCaseClass[RegulationModel]
}


case class RegulationApi(
                          regulationId: Option[Int] = None,
                          name: String,
                          description: Option[String],

                              [.... some other attributes....]


                          // Non Database fields
                          priceCategory: Option[PriceCategoriesModel],
                          slaLevel: Option[SlaLevelsModel],

                          markets: Option[Seq[MarketsModel]],
                          tags: Option[Seq[TagsModel]],
                          crawler: Option[CrawlerModel],

                          commentCreatedAt: Option[String],
                          creatorComment: Option[String],
                          approved: Option[Boolean],
                          approverComment: Option[String],
                          approvedAt: Option[String],
                          creatorUuid: Option[String],
                          approverUuid: Option[String],

                          regulationPackages: Option[Seq[RegulationPackagesModel]],
                          regulation_Evaluations: Option[Seq[Regulation_EvaluationModel]]
                        ) {
  def toModel: RegulationModel = {
    new RegulationModel(
      regulationId = this.regulationId,
      name = this.name,

          [.... some other attributes....]

      // Non Database fields
      priceCategory = None,
      slaLevel = None,
      markets = None,
      tags = None,
      crawler = None,
      commentCreatedAt = None,
      creatorComment = None,
      approved = None,
      approverComment = None,
      approvedAt = None,
      creatorUuid = None,
      approverUuid = None,
      regulationPackages = None,
      regulation_Evaluations = None
    )
  }
}

object RegulationApi {
  implicit val extendedRegulation_format: OFormat[RegulationApi] = Jsonx.formatCaseClass[RegulationApi]

  def fromModel(other: RegulationModel): RegulationApi = {
    RegulationApi(
      regulationId = other.regulationId,
      name = other.name,
      
          [.... some other attributes....]

      
      // Non Database fields
      priceCategory = None,
      slaLevel = None,
      markets = None,
      tags = None,
      crawler = None,
      commentCreatedAt = None,
      creatorComment = None,
      approved = None,
      approverComment = None,
      approvedAt = None,
      creatorUuid = None,
      approverUuid = None,
      regulationPackages = None,
      regulation_Evaluations = None
    )
  }
}


/**
  * Case Classes for Return types
  */

case class PmsFindingsWithTags(pmsFinding: RegulationModel, tags: Seq[TagsModel])

object PmsFindingsWithTags {
  implicit val pmsFindingsWithTags: OFormat[PmsFindingsWithTags] = Json.format[PmsFindingsWithTags]
}

case class PmsFindingsWithMarkets(pmsFinding: RegulationModel, markets: Seq[MarketsModel])

object PmsFindingsWithMarkets {
  implicit val pmsFindingsWithMarkets: OFormat[PmsFindingsWithMarkets] = Json.format[PmsFindingsWithMarkets]
}

case class PmsFindingsWithUrls(pmsFinding: RegulationModel, urls: Seq[CrawlerUrlsModel])

object PmsFindingsWithUrls {
  implicit val pmsFindingsWithMarkets: OFormat[PmsFindingsWithUrls] = Json.format[PmsFindingsWithUrls]
}

case class RegulationWithCrawler(regulation: RegulationModel, latestCrawlerResults: Seq[ResultsCrawlerModel], userUuid: Option[String])

object RegulationWithCrawler {
  implicit val regulationWithCrawlers: OFormat[RegulationWithCrawler] = Json.format[RegulationWithCrawler]
}

/**
  * Trait
  */

trait PmsFindingComponent {
  self: HasDatabaseConfigProvider[JdbcProfile] =>

  import profile.api._

  class Regulation(tag: Tag) extends Table[RegulationModel](tag, "Regulation") {
    def regulationId: Rep[Int] = column[Int]("regulationId", O.PrimaryKey, O.AutoInc)

    def name: Rep[String] = column[String]("name")

    def description: Rep[Option[String]] = column[Option[String]]("description")

          [.... some other attributes....]


    def shortDescriptionEn: Rep[Option[String]] = column[Option[String]]("shortDescriptionEn")

    def analysisEn: Rep[Option[String]] = column[Option[String]]("analysisEn")

    // HList-based wide case class mapping
    def * = (
      regulationId ::       name::
      description ::
      
      [.... some other attributes....]
      
      shortDescriptionEn::
      nameEn ::
      descriptionEn ::
      analysisEn :: HNil
      ).mappedWith(Generic[RegulationModel])
  }

  val regulation_query: TableQuery[Regulation] = TableQuery[Regulation] // Query object
}

但是我得到以下错误:

更新

想法是使用一个 HList 来表示一个 table 超过 22 列。

您不需要为此使用 slickless/shapeless,如果您不想,也不必使用 codegen,因为 built-in Slick HList 与 mapTo宏。

步骤是:

  1. 添加 HList 导入(并删除 slickless/shapeless 导入):

    import slick.collection.heterogeneous.{HList, HCons, HNil}
    import slick.collection.heterogeneous.syntax._
    
  2. 将您的 * 投影定义为:

    def * = (regulationId :: name :: etc... :: HNil).mapTo[RegulationModel]
    

现在 Slick 网站上有一个食谱部分来说明这一点:https://scala-slick.org/doc/3.3.3/cookbook.html#mapping-more-than-22-fields

如果您想了解有关此 22 限制的更多详细信息,这里有更长的 post:https://underscore.io/blog/posts/2016/10/11/twenty-two.html