Эмм... Я пробую Slick с Play 2. Процесс создания таблицы стал очень разочаровывающим, потому что, в отличие от других ORM (например, ebean), Slick не определяет, создана ли база данных, если таблица уже существует, он сообщит об исключении. Я просто не хочу бросать и создавать каждый раз, когда я перезагружаю сервер, поэтому я решил написать небольшую функцию, которая мне поможет:
def databaseCreate(tables: Table*) = {
for (table <- tables) {
if (MTable.getTables(table.getClass.getName).list.isEmpty) table.ddl.create
}
}
Что это делает, так это принимает некоторые объекты, подобные этому:
object Tag extends Table [(Option[Int], String)]("Tags") {
def id = column[Int]("TAG_ID", O.PrimaryKey, O.AutoInc)
def tag_name = column[String]("TAG_NAME")
def * = id.? ~ tag_name
}
И используйте метод MTable
из scala.slick.jdbc.meta.MTable
, чтобы узнать, существует таблица или нет. Затем я столкнулся с простой проблемой отражения Java. Если метод databaseCreate
принимает строки, я могу вызвать .ddl.create
. Поэтому я решил передать объекты и использовать reffection: table.getClass.getName
. Единственная проблема заключается в несоответствии типов: (из моей IDE)
Ожидаемый: MySQLDriver.simple.type#Table, фактический: BlogData.Tag.type
BlogData — это большой объект, который я использовал для хранения всех меньших объектов таблицы. Как решить эту проблему несоответствия?? Использовать целую кучу asInstanceOf
? Это сделало бы команду невыносимо длинной и уродливой...
Исправлено:
Несоответствие типов является ложной тревогой, которая исходит от IDE, а не от компилятора консоли typesafe. Настоящая проблема:
type Table takes type parameters
def databaseCreate(tables: Table*) = {
^
one error found
Затем я последовал совету и изменил код:
def databaseCreate(tables: Table[_]*)(implicit session: Session) = {
for (table <- tables) {
if (MTable.getTables(table.tableName).list.isEmpty) table.ddl.create
}
}
Затем я получил эту ошибку:
ambiguous implicit values: both value session of type slick.driver.MySQLDriver.simple.Session and method threadLocalSession in object Database of type => scala.slick.session.Session match expected type scala.slick.session.Session
if (MTable.getTables(table.tableName).list.isEmpty) table.ddl.create
^
one error found
Мой импорт здесь:
import play.api.GlobalSettings
import play.api.Application
import models.BlogData._
import scala.slick.driver.MySQLDriver.simple._
import Database.threadLocalSession
import play.api.Play.current
import scala.slick.jdbc.meta.MTable