0

I'm maintaing an old legacy application on Slick 2.1.0. When writing one piece, I ran into trouble with joins and made a query per each row in a query with the intent of fixing it later, but forgot to add a //TODO

row.code.flatMap(code => Option(getBundlesForCollection(code))),
row.code.flatMap(c => Option(getPricesForCollection(c)))

We've hit some preformance issues as this data set grew, so I wanted to fix it and get it right, but I rememebred all the issues I ran into. Right now my Slick queries are really simple. They look like the following:

def pricesForCollection(collectionCode : String)(implicit session : SessionDef) =
    prices.filter(_.collectionCode === collectionCode).run

So I looked back at the documentation and tried again to get a working join. If I do something like the following:

def getCollections(code : String)(implicit session: SessionDef) = {
  for {
    c <- collections.filter(_.code === code)
    pc <- prices if c.code === pc.collectionCode
    br <- collectionBundleRestrictions if c.code === br.collectionCode
  } yield(c, pc, br).run
}

I get compile errors I totally don't understand:

[error] Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List).
[error]   Required level: scala.slick.lifted.FlatShapeLevel
[error]      Source type: com.example.db.CollectionsRow
[error]    Unpacked type: T
[error]      Packed type: G
[error]       br <- collectionBundleRestrictions if c.code === br.collectionCode
[error]          ^

I've seen examples where you specify every column name (which makes sense) so I tried the following:

def getNewCollection(code : String)(implicit session: SessionDef) = {
  for {
    c <- collections.filter(_.code === code)
    pc <- prices if c.code === pc.collectionCode
    br <- collectionBundleRestrictions if c.code === br.collectionCode
  } yield(c.name, c.code,
    pc.priceCode, pc.iptcCategory, br.bundleRestrictionId,
    br.bundleRestrictionId).run
}

But then I get the following cryptic error at runtime:

[info] scala.slick.SlickException: No type for symbol s2 found for Ref s2
[info]  at scala.slick.ast.Ref.nodeWithComputedType2(Node.scala:501) ~[slick_2.11-2.1.0.jar:na]
[info]  at scala.slick.ast.Ref.nodeWithComputedType2(Node.scala:495) ~[slick_2.11-2.1.0.jar:na]
[info]  at scala.slick.ast.Node$class.nodeWithComputedType(Node.scala:101) ~[slick_2.11-2.1.0.jar:na]
[info]  at scala.slick.ast.Ref.nodeWithComputedType(Node.scala:495) ~[slick_2.11-2.1.0.jar:na]

There is a ton of documentation on how to make joins, but absoilutely none on iterating over the result set. How do I write and execute this join correctly?

Ideally I'd like a a tuple of (Collection,Seq[Prices],Seq[BundleRestrictions]), or something else that makes sense in a join process.

djsumdog
  • 2,560
  • 1
  • 29
  • 55

0 Answers0