Slick:Select 列不起作用
Slick: Select columns not working
我想简单地编写一个查询,它只为每个结果行获取一列(select title from...)而不是所有(select * ... from)。我的 SQL-查询将是:
select titel from Lied;
根据 http://slick.typesafe.com/doc/3.1.1/sql-to-slick.html?highlight=case#id3,我应该能够 select 只有几列,只需在光滑的 3.1 中做这样的事情:
people.map(p => (p.age, p.name ++ " (" ++ p.id.asColumnOf[String] ++ ")")).result
对我来说这意味着:
lieds.map(x => (x.titel)).result.map { println }
这行不通。日蚀说:
No matching Shape found. Slick does not know how to map the given types. Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List). Required level: slick.lifted.FlatShapeLevel Source type: slick.lifted.Rep[String] Unpacked type: T Packed type: G
我该如何解决?我想即使阅读了 scala slick method I can not understand so far(不确定这对 slick 3.1 是否仍然有效)和 slick 3.1 文档,我还是不能在这里结合一些基础知识。
我的Table(由 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))
如果你使用这个例子: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)
}
您可以 select 仅电子邮件字段使用
def getField(id: Long): Future[Option[String]] = {
dbConfig.db.run(users.filter(_.id === id).map(_.email).result.headOption)
}
问题已解决。
我不得不使用
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(或我?)最终将上述导入语句添加到我的 class 中,我在那里执行了 select.
正如您在我的问题中看到的那样,即使在其他查询正在运行时,只要我想使用 "map",我总是会遇到相同的错误(请参阅 Eclipse error mark)。
不过。通过简单地 import slick.driver.MySQLDriver.api._
替换那些导入语句解决了我的问题。还不知道为什么,但正如我们所有人所期望的那样,它现在可以正常工作了。如果你知道我/eclipse添加的导入有什么问题,请评论。
我想简单地编写一个查询,它只为每个结果行获取一列(select title from...)而不是所有(select * ... from)。我的 SQL-查询将是:
select titel from Lied;
根据 http://slick.typesafe.com/doc/3.1.1/sql-to-slick.html?highlight=case#id3,我应该能够 select 只有几列,只需在光滑的 3.1 中做这样的事情:
people.map(p => (p.age, p.name ++ " (" ++ p.id.asColumnOf[String] ++ ")")).result
对我来说这意味着:
lieds.map(x => (x.titel)).result.map { println }
这行不通。日蚀说:
No matching Shape found. Slick does not know how to map the given types. Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List). Required level: slick.lifted.FlatShapeLevel Source type: slick.lifted.Rep[String] Unpacked type: T Packed type: G
我该如何解决?我想即使阅读了 scala slick method I can not understand so far(不确定这对 slick 3.1 是否仍然有效)和 slick 3.1 文档,我还是不能在这里结合一些基础知识。
我的Table(由 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))
如果你使用这个例子: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)
}
您可以 select 仅电子邮件字段使用
def getField(id: Long): Future[Option[String]] = {
dbConfig.db.run(users.filter(_.id === id).map(_.email).result.headOption)
}
问题已解决。
我不得不使用
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(或我?)最终将上述导入语句添加到我的 class 中,我在那里执行了 select.
正如您在我的问题中看到的那样,即使在其他查询正在运行时,只要我想使用 "map",我总是会遇到相同的错误(请参阅 Eclipse error mark)。
不过。通过简单地 import slick.driver.MySQLDriver.api._
替换那些导入语句解决了我的问题。还不知道为什么,但正如我们所有人所期望的那样,它现在可以正常工作了。如果你知道我/eclipse添加的导入有什么问题,请评论。