Как вставить или обновить несколько строк в Slick в пакете

#scala #slick

Вопрос:

У меня есть гладкая модель, которую мне нужно создать или обновить на основе последовательности, указанной в методе insertOrUpdateCalculations. Если уже есть строка с (контейнер, заказ и поставщик), объем и вес должны быть обновлены. В противном случае следует создать новую строку.

 case class OrderCalculation(
  id: Long,
  container: Long,
  order: Long,
  vendor: Long,
  volume: Double,
  weight: Double)

class OrderCalculationTable(tag: Tag)
      extends Table[OrderCalculation](tag, "order_calculation") {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def order = column[Long]("containerOrder")
  def orderFk =
    foreignKey("order_fk", order, orderTbl)(_.id)
  def vendor = column[Long]("vendor")
  def vendorFk =
    foreignKey("vendor_fk", vendor, vendorTbl)(_.id)
  def container = column[Long]("container")
  def containerFk =
    foreignKey("container_fk", container, containerTbl)(_.id)
  def volume = column[Double]("volume")
  def weight = column[Double]("weight")
  override def * = (
    id,
    container,
    order,
    vendor,
    volume,
    weight
  ) <> ((OrderCalculation.apply _).tupled, OrderCalculation.unapply)
}
 

Мне нужно реализовать метод с подписью, как показано ниже:

 val orderCalculationTbl = TableQuery[OrderCalculationTable]
case class OrderCalculationSummary(
  orderId: Long,
  containerId: Long,
  vendorId: Long,
  volume: Double,
  weight: Double
 ) 
def insertOrUpdateCalculations(calculations: Seq[OrderCalculationSummary]): Future[Seq[OrderCalculation]] = db.run{
    /// insert or update each record here.
}
 

Моя основная проблема заключается в том, как обновить запись, если у меня нет первичного ключа (идентификатора) во входных значениях, а только 3 других значения, которые являются внешними ключами для других таблиц. В принципе, мне нужен запрос, который проверит эти 3 поля и обновит существующую или создаст новую строку без предоставления первичного ключа.

Комментарии:

1. В чем именно твоя проблема, чего ты не знаешь? Вот подробные документы о вставке строк scala-slick.org/doc/3.3.3/queries.html#inserting если вы хотите сначала загрузить данные из БД и выполнить различие самостоятельно. Существует также функция InsertOrUpdate op, если у вас есть необходимые ключи scala-slick.org/doc/3.3.3/queries.html#upserting

2. Из документации и примеров, которые я обнаружил, я не мог понять, как обновить существующую запись, если я не предоставлю первичный ключ, который является идентификатором. В моем случае у меня есть еще 3 поля, и мне нужно сделать запрос на их основе.

3. СУБД AFAIK полагаются на первичный ключ для вставки/замены в операции. Вам нужно сначала загрузить данные с помощью SELECT, выполнить различие, а затем выполнить обновления или или вставки. Боюсь, что коротких путей нет