Как отправлять простые SQL-запросы (и получать результаты) с помощью scala slick 3

Я пытаюсь создать класс, у которого есть методы, которые могут отправлять и получать данные в базу данных SQLite, используя простые запросы sql. К сожалению, это не работает. Я не хочу использовать неявные части withSession.

import slick.driver.SQLiteDriver.api._
import slick.lifted.TableQuery
import slick.jdbc.JdbcBackend.Database;
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import ExecutionContext.Implicits.global

    class DBops {
  val db = Database.forURL("jdbc:sqlite:S:/testing/testdb.sql",driver = "org.sqlite.JDBC")

def getData(TableName: String):Future[(Int,Double,String)]={
    db.run(sql"""select * from $TableName """.as[(Int,Double,String)])

}

}

Выдается следующая ошибка:

несоответствие типов; найдено: slick.profile.SqlStreamingAction [Vector [(Int, Double, String)], (Int, Double, String), slick.dbio.Effect] требуется: slick.dbio.DBIOAction [(Int, Double, String), slick .dbio.NoStream, ничего] DBops.scala


person Kyle Balkissoon    schedule 20.08.2015    source источник
comment
Проблема в том, что сгенерированный код будет select * from 'some_table'.   -  person Matias Saarinen    schedule 20.08.2015
comment
Интересно, помог ли мой ответ и правильно ли я понял вашу проблему?   -  person Matias Saarinen    schedule 21.08.2015
comment
Ответ был полезным, но не касался вопроса. Однако мне удалось решить это самостоятельно.   -  person Kyle Balkissoon    schedule 24.08.2015
comment
Рад слышать! На самом деле я не заметил отсутствия Seq в типе :)   -  person Matias Saarinen    schedule 24.08.2015


Ответы (2)


Вы можете использовать sql"..." с любым String контентом, используя #$tableName:

db.run(sql"SELECT * FROM #$tableName".as[(Int, Double, String)])

Пожалуйста, помните: никогда не принимайте tableName как вводимые пользователем данные - в противном случае существует большой риск внедрения SQL-кода. Обычный $value решает эти проблемы за вас.

Прочтите руководство Slick (http://slick.typesafe.com/doc/3.0.0/sql.html#splicing-literal-values)

... иногда вам нужно вставлять буквальные значения непосредственно в оператор, например, чтобы абстрагироваться от имен таблиц ... Для этой цели вы можете использовать # $ вместо $ во всех интерполяторах ...

person Matias Saarinen    schedule 20.08.2015
comment
Не буду воспринимать это как ввод пользователя, это только бэкэнд. Есть ли способ НЕ определять типы столбцов заранее? - person Kyle Balkissoon; 20.08.2015
comment
Вы имеете в виду sql"select...".as[(String, Int)]? Поскольку вы программируете на Scala, очень важно заранее определить типы - это безопасность типов. В основном вы можете использовать кортежи с любыми примитивными типами или создавать свои собственные implicit GetResult. Подробнее: slick.typesafe.com/doc/3.0.0 /sql.html#result-sets Плюс: я не вижу причин, по которым вы не могли создать GetResult, который бы создавал список, просто вызывая rs.next по набору результатов, но я не смог найти ссылку на это . - person Matias Saarinen; 20.08.2015

Я понял, что мне не хватает Seq в возвращаемом типе:

def getData(TableName: String): Future[Seq[(Int,Double,String)]] = {
  db.run(sql"""SELECT * FROM $TableName """.as[(Int, Double, String)])
}
person Kyle Balkissoon    schedule 24.08.2015