Есть ли способ сделать InsertAndUpdate с Slick, который будет выполнять только один запрос к БД? - PullRequest
0 голосов
/ 27 декабря 2018

Я обрабатываю большое количество событий, каждое из которых сохраняется в БД.Важно знать, была ли добавлена ​​новая строка или она уже существует.Метод Slick's insertOrUpdate возвращает 1 для обоих случаев, поэтому он не имеет значения для меня.моя таблица имеет 3 первичных ключа -> id, service, filename. Я попытался использовать следующий код, который работает и возвращает 1 в случае новой строки и 0 в случае существующей строки, но он неэффективен, поскольку в конечном итогегенерирует 2 запроса к БД:

def updateOrInsertEvent(rowToAddOrUpdate: TableRow): Future[Int] = { 
    val insertOrUpdateAction = table.filter(r =>
      r.id === rowToAddOrUpdate.id && r.service ===        
      rowToAddOrUpdate.service && r.fileName === rowToAddOrUpdate.fileName)
      .result.headOption.flatMap{
          case Some(_) =>
            DBIO.successful(0)
          case None =>
            taskEventStatusTable.insertOrUpdate(rowToAddOrUpdate)
    }
    db.run(insertOrUpdateAction.transactionally)
 }

Вместо этого я пытаюсь выполнить собственный запрос, используя Slick.При выполнении следующего запроса непосредственно к MySQL он возвращает 1 в случае новой строки, 2 в случае обновленной строки и 0 в случае отсутствия изменений.Когда он запускается через Slick, он всегда возвращает 1.

def updateOrInsertEvent(rowToAddOrUpdate: TableRow): Future[Int] = { 
    def insertOrUpdate =
        sqlu"""insert into TASK_EVENT_STATUS (ID, SERVICE, FILENAME, 
        SET_ID) values(${rowToAddOrUpdate.id}, ${rowToAddOrUpdate.service}, 
         ${rowToAddOrUpdate.filename}, ${rowToAddOrUpdate.setId}) on 
         duplicate key update SET_ID=${taskEventStatus.setId}"""

    db.run(insertOrUpdate)
}

Кто-нибудь знает, как мне изменить один из приведенных выше вариантов, чтобы предоставить мне один вызов запроса, который вернет ожидаемый результат 1/0?

...