play-slick : not found table - scala

I want to use play-slick 1.0.0 with play 2.4.0.
According to the sample (https://github.com/playframework/play-slick/tree/master/samples/basic), I defined the UserTable like this:
package tables
import models.User
import scala.slick.driver.JdbcProfile
trait UserTable {
protected val driver: JdbcProfile
import driver.api._
class Users(tag: Tag) extends Table[User](tag, "users"){
def ID = column[Long]("id", O.PrimaryKey, O.AutoInc)
def email = column[String]("email", O.NotNull)
def password = column[String]("password", O.NotNull)
def * = (ID, email, password) <> (User.tupled, User.unapply)
}
}
And I implemented the controller as follow:
package controllers
import play.api._
import play.api.mvc._
import play.api.db.slick.DatabaseConfigProvider
import play.api.db.slick.HasDatabaseConfig
import tables.UserTable
import scala.slick.driver.JdbcProfile
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import models.User
import tables.UserTable
class UserController extends Controller with UserTable with HasDatabaseConfig[JdbcProfile]{
val dbConfig = DatabaseConfigProvider.get[JdbcProfile](Play.current)
import driver.api._
val Users = TableQuery[Users]
def index = Action.async {
db.run(Users.result).map(res => Ok(views.html.User.index(res.toList)))
}
}
But, I ran the application and invoked this controller, I got the error
[SQLException: [SQLITE_ERROR] SQL error or missing database (no such table: users)]
How can I create the "users" table?

You need to either use an existing users table or create a table through slick.
Please see http://slick.typesafe.com/doc/3.0.0/gettingstarted.html#populating-the-database
You need to run db.run(Users.schema.create) in your application.

Related

Error: value <> is not a member of. Slick

i new in Scala. I going through tutorial and try to create something useful, but faced with strange error like this:
value <> is not a member of (slick.lifted.Rep[Long], slick.lifted.Rep[String], slick.lifted.Rep[String], slick.lifted.Rep[String])
My code:
package models
import java.sql.Timestamp
import slick.jdbc.MySQLProfile._
import slick.jdbc.MySQLProfile.api.stringColumnType
import slick.jdbc.MySQLProfile.api.longColumnType
import slick.jdbc.MySQLProfile.api.timestampColumnType
import slick.lifted.Tag
case class User(id: Long, name: String, email: String, PMAccount: String)
class Users(tag: Tag) extends Table[User](tag, "Users") {
def id = column[Long]("id")
def name = column[String]("name")
def email = column[String]("email")
def PMAccount = column[String]("PMAccount")
def * = (id, name, email, PMAccount) <> (User.tupled, User.unapply(_))
}
Can anyone help me to understand this ?
You have forgotten to import necessary api, just add this line to your code and it should work
import database.driver.api._
def * = (id, name, email, PMAccount) <> (User.tupled, User.unapply(_))

slick column not defined

I am new in scala slick .
why can not found column and O in slick v3.1.1
please view this example code :
import slick.driver.PostgresDriver
import slick.lifted.Tag
import slick.model.Table ;
case class Person(id:Int,name:String)
class Persons(tag: Tag) extends Table[Person](tag , "PERSONS") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name", O.NotNull)
}
Update :
I use this document : http://slick.lightbend.com/doc/3.1.1/gettingstarted.html#schema
Simply change your import to:
import slick.driver.PostgresDriver.api._
Looking at your code - this should be the only import that you should need (at least at this stage).
For the latest versions of slick you can use:
import slick.jdbc.PostgresProfile.api._
So you don't see the deprecated message

connecting slick 3.1.1 to the database

I have the following code and I'm trying to connect to the MySQL database without success.
cat Database.scala
package com.github.odnanref.EmailFilter
import slick.driver.MySQLDriver._
import slick.driver.MySQLDriver.backend.Database
/**
* Created by andref on 12/05/16.
*/
class Database {
val url = "jdbc:mysql://localhost/playdb"
val db = Database.forURL(url, driver = "com.mysql.jdbc.Driver")
override def finalize() {
db.close()
super.finalize()
}
}
cat EmailMessageTable.scala
package com.github.odnanref.EmailFilter
import java.sql.Timestamp
import slick.driver.JdbcProfile
import slick.driver.MySQLDriver.api._
import scala.concurrent.Future
class EmailMessageTable(tag: Tag) extends Table[EmailMessage](tag, "email_message") {
def id = column[Option[Long]]("id", O.AutoInc, O.PrimaryKey)
def email = column[String]("email")
def subject = column[String]("subject")
def body = column[String]("body")
def datain = column[Timestamp]("datain")
def email_id= column[Long]("email_id")
def * = (id, email, subject, body, datain, email_id) <> ((EmailMessage.apply _).tupled, EmailMessage.unapply)
def ? = (id.get.?, email.?, subject.?, body.?, datain.?).shaped.<>({ r =>; _1.map(_ =>
EmailMessage.tupled((_1, _2.get, _3.get, _4.get, _5.get))) }, (_: Any) =>
throw new Exception("Inserting into ? projection not supported."))
}
I can't initialize the database and execute search query's or insert statements based on this code I try to do
val db = new Database()
db.db.run(TableQuery[EmailMessageTable] += EmailMessage(...) )
And it says, it doesn't know the method +=
Also I get this error:
Database.scala:4: imported `Database' is permanently hidden by definition of class Database in package EmailFilter
[warn] import slick.driver.MySQLDriver.backend.Database
What am I doing wrong?
Post EDIT>
package com.github.odnanref.EmailFilter
import java.sql.Timestamp
case class EmailMessage(
id: Option[Long],
email: String,
subject:String,
body:String,
datain: Timestamp,
email_id: Long
)
You are importing a class named Database inside a file that defines another class with the same name. You can:
rename your Database class:
class MyDatabase {
val url = ...
val db = ...
...
}
rename imported class:
import slick.driver.MySQLDriver.backend.{Database => SlickDB}
...
val db = SlickDB.forURL(url, driver = "com.mysql.jdbc.Driver")
avoid importing Database explicitly:
import slick.driver.MySQLDriver.backend
...
val db = backend.Database.forURL(url, driver = "com.mysql.jdbc.Driver")

Deleting is not working with Play! 2.4, Slick 3 and PostgreSQL

I have read this SO post: Play 2.4 - Slick 3.0.0 - DELETE not working
but it seems not to work in my case.
I manage to insert or get some data from my PostgreSQL (9.1) database in my Play! 2.4 application, but I don't manage to perform some deletions.
Here is the very simple code of my controller:
package controllers
import javax.inject.Inject
import play.api.db.slick.DatabaseConfigProvider
import play.api.mvc._
import slick.driver.JdbcProfile
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import slick.driver.PostgresDriver.api._
import models.Address
class Application #Inject()(dbConfigProvider: DatabaseConfigProvider) extends Controller {
val dbConfig = dbConfigProvider.get[JdbcProfile]
import dbConfig._
import dbConfig.driver.api._
def index = Action.async {
db.run(addresses.filter(_.id === 1L).delete) map { res =>
Ok(Json.toJson(res))
}
}
}
and my model Address:
case class Address(id: Option[Long], city: String)
object Address {
class Addresses(tag: Tag) extends Table[Address](tag, "addresses") {
def id = column[Long]("addressid", O.PrimaryKey, O.AutoInc)
def city = column[String]("city")
def * = (id.?, city) <>
((Address.apply _).tupled, Address.unapply)
}
lazy val addresses = TableQuery[Addresses]
}
The compilation error I get is: value delete is not a member of slick.lifted.Query[models.Address.Addresses,models.Address.Addresses#TableElementType,Seq]
I suspect that it comes from the imports, but I tried a lot of things without any improvement.
I suspect that the problem is that you are importing the implicits needed for the delete function twice, thus generating an ambiguity and causing the compiler to give up on that:
import slick.driver.PostgresDriver.api._
import dbConfig.driver.api._
You don't probably need one of the two anyway, if you are trying to be generic (e.g. because you want to run tests over H2) try removing the PostgresDriver import. If that doesn't work try removing the inner import and leave PostgresDriver as the SO post you linked seemed to suggest that delete was (is?) not in the common API.

slick 'n scala : a TableQuery object without .ddl field

using scala, slick 2.0 & eclipse I have an error I can't explain : "value ddl is not a member of scala.slick.lifted.TableQuery[SqliteSpec.this.Personnes]"
here is the code:
I declare a trait like this :
trait sqlite {
val db = Database.forURL("jdbc:sqlite:rdvs.txt", driver = "org.sqlite.JDBC")
class Personnes(tag: Tag) extends Table[Rdv](tag, "RDV") {
def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
def nom = column[String]("NOM", O.NotNull)
def prénom = column[String]("PRENOM")
def sexe = column[Int]("SEXE")
def télPortable = column[String]("TELPOR")
def télBureau = column[String]("TELBUR")
def télPrivé = column[String]("TELPRI")
def siteRDV = column[String]("SITE")
def typeRDV = column[String]("TYPE")
def libelléRDV = column[String]("LIBELLE")
def numRDV = column[String]("NUMRDV")
def étape = column[String]("ETAPE")
def dateRDV = column[Date]("DATE")
def heureRDVString = column[String]("HEURE")
def statut = column[String]("STATUT")
def orderId = column[String]("ORDERID")
def * = (id.?, nom, prénom, sexe, télPortable, télBureau, télPrivé,
siteRDV, typeRDV, libelléRDV, numRDV, étape, dateRDV, heureRDVString,
statut, orderId) <> (Rdv.tupled, Rdv.unapply _)
}
}
and here is the wrong code :
db.withDynSession{
val personnes=TableQuery[Personnes]
personnes.ddl.create
}
althought I followed this official tutorial : http://slick.typesafe.com/doc/2.0.0/schemas.html (section DDL)
Do you know what's wrong?
thanks.
Maybe this is useful for somebody: I had the same problem, but my mistake was importing different driver simple implicits. In my main model class had Postgres', but in my tests had H2's (in order to make in-memory integration testing). Switching to the same drivers solved the issue.
I would like to add the entire code, but the "edit" button is no more present under my question; here is the code:
package tests {
#RunWith(classOf[JUnitRunner])
class SqliteSpec extends Specification with sqlite {
"la base sqlite" should {
"create a new database file" in new Sqlite_avant_chaque_test {
todo
}
}
class Sqlite_avant_chaque_test extends Scope {
println("avant test")
def abc = {
db.withDynSession {
val personnes = TableQuery[Personnes]
personnes.ddl.create
}
}
}
}
}
ok, I only needed to log on; here is the working code :
import org.specs2.execute.AsResult
import org.specs2.runner.JUnitRunner
import scala.collection.GenTraversableOnce
import org.specs2.time.TimeConversions$longAsTime
import org.specs2.collection.BiMap
import org.specs2.control.Debug$Debuggable
import scala.collection.mutable.ListBuffer
import org.specs2.internal.scalaz.TreeLoc
import org.specs2.mutable.Specification
import scala.xml.NodeSeq
import scala.collection.immutable.List
import org.specs2.text.LinesContent
import org.specs2.specification.Fragments
import scala.math.Numeric
import java.net.URL
import org.specs2.matcher.MatchSuccess
import scala.runtime.Nothing$
import scala.reflect.ClassTag
import org.specs2.main.Arguments
import java.io.InputStream
import org.specs2.data.Sized
import org.junit.runner.RunWith
import org.specs2.specification.Scope
import java.sql.SQLInvalidAuthorizationSpecException
import models.sqlite
import scala.slick.lifted.TableQuery
//import scala.slick.driver.JdbcDriver.simple._
import scala.slick.driver.SQLiteDriver.simple._
import play.api.test.Helpers
import play.test.Helpers
package tests {
#RunWith(classOf[JUnitRunner])
class SqliteSpec extends Specification with sqlite {
sequential
"la base sqlite" should {
"create a new database file" in new Sqlite_avant_chaque_test {
todo
}
}
class Sqlite_avant_chaque_test extends Scope {
println("avant test")
//db.withDynSession {
db.withSession { implicit session: Session =>
val personnes = TableQuery[Personnes]
personnes.ddl.create
println("avant tests, après création base")
}
}
}
}