【问题标题】:Slick: Select columns not working光滑:选择列不起作用
【发布时间】:2016-08-17 00:20:05
【问题描述】:

我想简单地编写一个查询,它只为每个结果行获取一列(从...中选择标题),而不是全部(选择*...来自)。我的 SQL 查询是:

select titel from Lied;

根据http://slick.typesafe.com/doc/3.1.1/sql-to-slick.html?highlight=case#id3,我应该能够通过简单地在 slick 3.1 中执行类似的操作来仅选择几列:

people.map(p => (p.age, p.name ++ " (" ++ p.id.asColumnOf[String] ++ ")")).result

对我来说,这意味着:

lieds.map(x => (x.titel)).result.map { println }

这不起作用。日食说:

找不到匹配的形状。 Slick 不知道如何映射给定的类型。可能的原因: Table[T] 中的 T 与您的 * 投影不匹配。或者您在查询中使用不受支持的类型(例如 scala 列表)。所需级别:slick.lifted.FlatShapeLevel 源类型:slick.lifted.Rep[String] 未打包类型:T 打包类型:G

我应该如何解决这个问题?我想我还不能在这里结合一些基础知识,即使阅读了scala slick method I can not understand so far(不确定这是否仍然适用于 slick 3.1)和 slick 3.1 文档。

我的表(从 slick 生成):

  case class LiedRow(id: Long, titel: String, rubrikId: Option[Long] = None, stichwoerter: Option[String] = None, bemerkungen: Option[String] = None, createdAt: Option[java.sql.Timestamp] = None, updatedAt: Option[java.sql.Timestamp] = None, externallink: Option[String] = None, lastedituserId: Long, tonality: Option[String] = None)

  implicit def GetResultLiedRow(implicit e0: GR[Long], e1: GR[String], e2: GR[Option[Long]], e3: GR[Option[String]], e4: GR[Option[java.sql.Timestamp]]): GR[LiedRow] = GR{
    prs => import prs._
    LiedRow.tupled((<<[Long], <<[String], <<?[Long], <<?[String], <<?[String], <<?[java.sql.Timestamp], <<?[java.sql.Timestamp], <<?[String], <<[Long], <<?[String]))
  }

  class Lied(_tableTag: Tag) extends Table[LiedRow](_tableTag, "lied") {
    def * = (id, titel, rubrikId, stichwoerter, bemerkungen, createdAt, updatedAt, externallink, lastedituserId, tonality) <> (LiedRow.tupled, LiedRow.unapply)
    def ? = (Rep.Some(id), Rep.Some(titel), rubrikId, stichwoerter, bemerkungen, createdAt, updatedAt, externallink, Rep.Some(lastedituserId), tonality).shaped.<>({r=>import r._; _1.map(_=> LiedRow.tupled((_1.get, _2.get, _3, _4, _5, _6, _7, _8, _9.get, _10)))}, (_:Any) =>  throw new Exception("Inserting into ? projection not supported."))


    val id: Rep[Long] = column[Long]("id", O.AutoInc, O.PrimaryKey)
    val titel: Rep[String] = column[String]("Titel")
    val rubrikId: Rep[Option[Long]] = column[Option[Long]]("rubrik_id", O.Default(None))
    val stichwoerter: Rep[Option[String]] = column[Option[String]]("Stichwoerter", O.Default(None))
    val bemerkungen: Rep[Option[String]] = column[Option[String]]("Bemerkungen", O.Default(None))
    val createdAt: Rep[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("created_at", O.Default(None))
    val updatedAt: Rep[Option[java.sql.Timestamp]] = column[Option[java.sql.Timestamp]]("updated_at", O.Default(None))
    val externallink: Rep[Option[String]] = column[Option[String]]("externalLink", O.Default(None))
    val lastedituserId: Rep[Long] = column[Long]("lastEditUser_id")
    val tonality: Rep[Option[String]] = column[Option[String]]("tonality", O.Length(30,varying=true), O.Default(None))

    lazy val rubrikFk = foreignKey("liedRubrik", rubrikId, Rubrik)(r => Rep.Some(r.id), onUpdate=ForeignKeyAction.Cascade, onDelete=ForeignKeyAction.NoAction)
    lazy val userFk = foreignKey("liedLastEditUser", lastedituserId, User)(r => r.id, onUpdate=ForeignKeyAction.Cascade, onDelete=ForeignKeyAction.NoAction)
  }
  lazy val Lied = new TableQuery(tag => new Lied(tag))

【问题讨论】:

  • 我没有完全理解你的问题,但也许这个教程可以帮助你:pedrorijo.com/blog/play-slick
  • 感谢您的链接。我已经看到了。不幸的是,我在那里找不到可以回答我问题的东西。我怎样才能澄清我的问题?一句话,我想要一个只选择一列(标题)而不是全部(*)的光滑语句,因为我不需要该特定查询中其他列的值。
  • 应该像def getTitelById(id: Long) = lieds.filter(_.id === id).map(_.titel)一样简单,然后你可以使用db.run(getTitelById(1032L)得到一个Future[String]

标签: mysql scala slick


【解决方案1】:

如果你使用这个例子:https://github.com/pedrorijo91/play-slick3-steps/blob/master/app/models/User.scala

而不是:

 def get(id: Long): Future[Option[User]] = {
    dbConfig.db.run(users.filter(_.id === id).result.headOption)
  }

您可以使用

仅选择电子邮件字段
  def getField(id: Long): Future[Option[String]] = {
    dbConfig.db.run(users.filter(_.id === id).map(_.email).result.headOption)
  }

【讨论】:

  • 我同意。我能够e。 G。在 typesafe (github.com/typesafehub/activator-hello-slick#slick-3.0) 的 hello-slick-3.0 示例中编写这样的查询,但是使用我生成的 Lied-Table 我仍然有相同的错误:未找到匹配的形状。我只是不知道我的代码有什么区别......
【解决方案2】:

问题解决了。

我不得不使用

import slick.driver.MySQLDriver.api._

而不是

import slick.driver.MySQLDriver.api.DBIO
import slick.driver.MySQLDriver.api.Database
import slick.driver.MySQLDriver.api.columnExtensionMethods
import slick.driver.MySQLDriver.api.longColumnType
import slick.driver.MySQLDriver.api.streamableQueryActionExtensionMethods
import slick.driver.MySQLDriver.api.valueToConstColumn

当我在玩不同的查询时,eclipse(或我?)最终将上述导入语句添加到我执行选择的类中。

正如您在我的问题中看到的那样,即使在其他查询正在运行时,只要我想使用“地图”,我总是会遇到相同的错误(请参阅 Eclipse error mark)。

但是。用简单的import slick.driver.MySQLDriver.api._ 替换那些导入语句解决了我的问题。还不知道为什么,但它现在正如我们所有人所期望的那样工作。如果您知道我/eclipse 添加的导入出了什么问题,请发表评论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多