Reputation: 139
This is in a Scala Play project using to connect to MariaDB.
cat build.sbt
...
jdbc,
"org.mariadb.jdbc" % "mariadb-java-client" % "2.6.2",
"com.typesafe.slick" %% "slick" % "3.3.2",
...
class Users(tag: Tag) extends Table[(...)](tag, "USERS") {...}
val users = TableQuery[Users]
for (u <- users) {...}
Error:
value foreach is not a member of slick.lifted.TableQuery[controller.Users]
for (u <- users) {
^
I tried adding .result
to users
in the for loop, but I got
value foreach is not a member of slick.jdbc.MySQLProfile.StreamingProfileAction[Seq[controller.Users#TableElementType],controller.Users#TableElementType,slick.dbio.Effect.Read]
for (u <- users.result) {
^
I don't have db.run
anywhere in the code.
Upvotes: 0
Views: 1221
Reputation: 4330
It looks like you want to iterate over the users in your database.
There are a couple of concepts that you need here:
The expression users
is a kind of query. Methods like map
and filter
are a way to produce alternative queries. Iterating over a query, with a foreach
, doesn't really make sense.
With users.results
you have an action (a kind of DBIOAction
). This is something you might send to the database, with a db.run
. Again, methods like map
or flatMap
are a way to convert and combine actions, but iterating over an action with foreach
, doesn't really make sense.
So what to do? The signature of users.result
is something like DBIO[Seq[User]]
. If you want to do something to each user, maybe print them out, you can construct an action to do that. One way is to map
the result of the action (a list of users) to something else. Maybe:
val doSomethingWithEachUser: DBIO[Unit] =
users.result.map { seqUsers =>
seqUsers.foreach(println)
}
Here we've used map
to change the result type of the DBIO[Seq[User]]
into a DBIO[Unit]
.
You can then send doSomethingWithEachUser
to the database (so to speak) with db.run
. When you do that, your action is run, and when the values are available, the println
will happen.
To switch back to a for comprehension, you can see that we need to construct a new action:
val doSomethingWithEachUser: DBIO[Unit] =
for {
allUsers <- messages.result
} yield allUsers.foreach(println)
...for example.
The next layer on would be in Future
, which is the result from db.run
. You could also use a map
(or similar) on a future to work with the data. Slick is pretty much all about these kinds of building blocks of queries, actions, and (finally) futures, and manipulating them with combinators like map
and flatMap
.
Upvotes: 1