Как определить необязательный внешний ключ в Slick?

У меня есть такая таблица:

object Addresses extends Table[AddressRow]("address") {
   def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def street = column[String]("street")
  def number = column[String]("number")
  def zipcode = column[String]("zipcode")
  def city = column[String]("city")
  def country = column[String]("country")
  def geoLocationId = column[Int]("geo_location_id", O.Nullable)

 // Foreign keys.
 def geoLocation = foreignKey("fk_geo_location", geoLocationId, GeoLocations)(_.id)

 // Rest of my code.
 ...
}

где мой класс case:

case class AddressRow(
  id: Option[Int] = None,
  street: String,
  number: String,
  zipcode: String,
  city: String,
  country: String,
  geoLocationId: Option[Int])

Как вы заметили, геолокация является необязательным внешним ключом....

Я не могу найти способ описать это «необязательно» в моем определении внешнего ключа.

Я пробовал как:

  def geoLocation = foreignKey("fk_geo_location", geoLocationId.asColumnOf[Option[Int]], GeoLocations)(_.id)

но я получаю:

Вызвано: scala.slick.SlickException: невозможно использовать столбец Apply Function Cast в ограничении внешнего ключа (разрешены только именованные столбцы)

У кого-нибудь есть предложение?


person Cristian Boariu    schedule 12.03.2013    source источник


Ответы (2)


Я не думаю, что то, что вы пытаетесь сделать, можно выполнить с помощью внешних ключей. Ознакомьтесь с присоединением и определяемые пользователем типы из Slick документы

Обратите внимание на пример с leftJoin:

val explicitLeftOuterJoin = for {
  (c, s) <- Coffees leftJoin Suppliers on (_.supID === _.id)
} yield (c.name, s.name.?)

Итак, если вы хотите запросить все ваши Addresses, вам нужно начать с чего-то вроде

val addressGeolocQuery = for {
  (addr, loc) <- Addresses leftJoin GeoLocations on (_.geoLocationId === _.id)
} yield addr.id ~ loc.prop1.? ~ loc.prop2.? /*and so on*/

Затем вы можете сопоставить результаты этого запроса, чтобы получить фактический экземпляр Address вместе с Option[GeoLocation]. Вот почему я связал «определяемые пользователем типы» в документации... это новая функция для меня (я был знаком с ScalaQuery, который был предыдущим воплощением Slick), но он выглядит довольно многообещающе.

person Dylan    schedule 12.03.2013

Попробуйте следующее:

def geoLocationId = column[Option[Int]]("geo_location_id")
//Foreign Key
def geoLocation = foreignKey("fk_geo_location", geoLocationId, GeoLocations)(_.id.?)

geoLocationId теперь является столбцом Option[Int], поэтому O.Nullable больше не нужен (_.id.?) возвращает GeoLocation в качестве опции или None, если он был нулевым.

person Wellingr    schedule 24.09.2013