Slick 3.0.0 - how to query when an optional field is involved

4,517 views
Skip to first unread message

Leandro Komosinski

unread,
May 27, 2015, 2:27:21 PM5/27/15
to scala...@googlegroups.com
  Hi,

   Please, consider code below.

case class Seat(id: Int, code: String, observation: Option[String])


class Seats(tag: Tag)  extends Table[Seat](tag, "seats") {
 
def id = column[Int]("id", O.PrimaryKey)
 
def code = column[String]("code")
 
def observation = column[Option[String]]("observation")
 
def * = (id, code, observation) <> (Seat.tupled, Seat.unapply)
}

val seats = TableQuery[Seats]

How must I code the query "find all seats with no observation"? Compiler doesn't accept this

seats.filter(_.observation === None)

I wish create a method like this

def findAllSeatsWithoutObservation = {
  db
.run(seats.filter(_.observation === None).result)
}


 Thanks,

Leandro


Naftoli Gugenheim

unread,
May 27, 2015, 2:59:23 PM5/27/15
to scala...@googlegroups.com
On Wed, May 27, 2015 at 2:27 PM Leandro Komosinski <leandro.k...@gmail.com> wrote:
  Hi,

   Please, consider code below.

case class Seat(id: Int, code: String, observation: Option[String])


class Seats(tag: Tag)  extends Table[Seat](tag, "seats") {
 
def id = column[Int]("id", O.PrimaryKey)
 
def code = column[String]("code")
 
def observation = column[Option[String]]("observation")
 
def * = (id, code, observation) <> (Seat.tupled, Seat.unapply)
}

val seats = TableQuery[Seats]

How must I code the query "find all seats with no observation"? Compiler doesn't accept this

seats.filter(_.observation === None)


Does it give you any information about why it doesn't accept it? Because if it does it might be helpful to share it. :)
 
I wish create a method like this

def findAllSeatsWithoutObservation = {
  db
.run(seats.filter(_.observation === None).result)
}



Does _.observation.isEmpty work?
 
 Thanks,

Leandro


--

---
You received this message because you are subscribed to the Google Groups "Slick / ScalaQuery" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scalaquery+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/scalaquery/6d878d3c-57d4-404d-b40f-02b8c63bc970%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Leandro Komosinski

unread,
May 27, 2015, 3:06:48 PM5/27/15
to scala...@googlegroups.com
 No, because _.observation type is Rep[Option[String]] and not Option[String].

And that is precisely the point: why there is no implicit conversion from Option[String] to Rep[Option[String]] as is the case in any other types.

Naftoli Gugenheim

unread,
May 28, 2015, 1:04:09 AM5/28/15
to scala...@googlegroups.com


On Wed, May 27, 2015, 3:06 PM Leandro Komosinski <leandro.k...@gmail.com> wrote:

 No, because _.observation type is Rep[Option[String]] and not Option[String].

I know that. There are extension methods though.
Are you importing driver.simple._ or driver.api._ ?

And that is precisely the point: why there is no implicit conversion from Option[String] to Rep[Option[String]] as is the case in any other types.

You mean the reverse?


--

To view this discussion on the web visit https://groups.google.com/d/msgid/scalaquery/6f649873-36be-440b-8a32-4b2dca2a9d2a%40googlegroups.com.

Leandro Komosinski

unread,
May 29, 2015, 2:55:17 AM5/29/15
to scala...@googlegroups.com
This is my import

import slick.driver.H2Driver.api._


The same error happens with code below:

class X(tag: Tag) extends Table[(Int, Option[String])](tag, "X") {

   
def id = column[Int]("id", O.PrimaryKey)

   
def name = column[Option[String]]("name")
   
def * = (id, name)
 
}



 
val x = TableQuery[X]


def getAllXWithNameNone = {
    db
.run(x.filter(_.name === None).result)
 
}



Compiler error message is:


ambiguous implicit values:  both value BooleanColumnCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[slick.lifted.Rep[Boolean]]  and value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[slick.lifted.Rep[Option[Boolean]]]  match expected type slick.lifted.CanBeQueryCondition[Nothing]  

Leandro Komosinski

unread,
May 29, 2015, 4:34:37 AM5/29/15
to scala...@googlegroups.com
Solved! (but I'm not sure it's the recommended way)

def getAllXWithNameNone = {
  db
.run(x.filter( _.name.column.isEmpty).result)
}


Slick's docs (http://slick.typesafe.com/doc/3.0.0/queries.html) could show an example about this case.

Naftoli Gugenheim

unread,
May 29, 2015, 5:01:12 AM5/29/15
to scala...@googlegroups.com
On Fri, May 29, 2015 at 2:55 AM Leandro Komosinski <leandro.k...@gmail.com> wrote:
This is my import

import slick.driver.H2Driver.api._



And I think api should extend ExtensionMethodConversions. Out of curiosity what happens if you write t => anyOptionColumnExtensionMethods(t.column).isEmpty? Does it not find the definition of anyOptionColumnExtensionMethods, or is there some type error somehow?

General rule: if you want to know why an implicit is not being inserted, try it explicitly and see what error you get.


 

The same error happens with code below:

class X(tag: Tag) extends Table[(Int, Option[String])](tag, "X") {

   
def id = column[Int]("id", O.PrimaryKey)

   
def name = column[Option[String]]("name")
   
def * = (id, name)
 
}



 
val x = TableQuery[X]


def getAllXWithNameNone = {
    db
.run(x.filter(_.name === None).result)
 
}



Compiler error message is:


ambiguous implicit values:  both value BooleanColumnCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[slick.lifted.Rep[Boolean]]  and value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[slick.lifted.Rep[Option[Boolean]]]  match expected type slick.lifted.CanBeQueryCondition[Nothing]  


I think that usually means there's another error message and this one is just a domino effect. Where else is it getting the Nothing from?
 

Naftoli Gugenheim

unread,
May 29, 2015, 5:04:06 AM5/29/15
to scala...@googlegroups.com
On Fri, May 29, 2015 at 4:34 AM Leandro Komosinski <leandro.k...@gmail.com> wrote:
Solved! (but I'm not sure it's the recommended way)

def getAllXWithNameNone = {
  db
.run(x.filter( _.name.column.isEmpty).result)
}



Strange. Can your IDE tell us where the `column` method is coming from?
 

Leandro Komosinski

unread,
May 29, 2015, 1:56:24 PM5/29/15
to scala...@googlegroups.com
I'm using Eclipse. It shows column as a field of slick.lifted.ColumnOrdered

Leandro Komosinski

unread,
May 29, 2015, 2:11:21 PM5/29/15
to scala...@googlegroups.com


Em sexta-feira, 29 de maio de 2015 06:01:12 UTC-3, nafg escreveu:


On Fri, May 29, 2015 at 2:55 AM Leandro Komosinski <leandro.k...@gmail.com> wrote:
This is my import

import slick.driver.H2Driver.api._



And I think api should extend ExtensionMethodConversions. Out of curiosity what happens if you write t => anyOptionColumnExtensionMethods(t.column).isEmpty? Does it not find the definition of anyOptionColumnExtensionMethods, or is there some type error somehow?

  Same error:

ambiguous implicit values:  both value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[slick.lifted.Rep[Option[Boolean]]]  and value BooleanCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[Boolean]  match expected type slick.lifted.CanBeQueryCondition[Nothing]  

 
Reply all
Reply to author
Forward
0 new messages