SLICK: для вставки значения в 3 разные таблицы с помощью одного простого вызова API - PullRequest
0 голосов
/ 17 февраля 2020

Вопрос относится к слику: у меня есть три таблицы:
1) Пользователи
2) Team2members
3) Team2Owners

В своем посте к пользователям я передаю значения memberOf и managerOf, эти значения будут вставлены в таблицы Team2members и Team2Owners соответственно, а не в таблицу Users. Хотя другие значения запроса на публикацию будут вставлены в таблицу «Пользователи».

Запрос «Моя почта» выглядит следующим образом:

{"kind": "via#user",
      "userReference":{"userId":"priya16"},
      "user":"preferredNameSpecialChar@domain1.com","memberOf":{"teamReference":{"organizationId":"airtel","teamId":"supportteam"}},
       "managerOf":{"teamReference":{"organizationId":"airtel","teamId":"supportteam"}},
      "firstName":"Special_fn1",
      "lastName":"specialChar_ln1",
      "preferredName":[{"locale":"employee1","value":"@#$%^&*(Z0FH"}],
      "description":" preferredNameSpecialChar test "}  

Я формирую запрос, показанный ниже:
Кажется, что запрос работает нормально, когда определено только memberInsert, когда я пытаюсь определить оба значения, например memberInsert и managerInsert, тогда вставка происходит только для второго значения.

val query = config.api.customerTableDBIO(apiRequest.parameters.organizationId).flatMap { tables =>
      val userInsert = tables.Users returning tables.Users += empRow
      val memberInsert = inputObject.memberOf.map(m => m.copy(teamReference = m.teamReference.copy(organizationId = apiRequest.parameters.organizationId))).map { r =>
        for {
          team2MemberRow <- tables.Team2members returning tables.Team2members += Teams2MembersEntity.fromEmtToTeams2Members(r, empRow.id)
          team <- tables.Teams.filter(_.id === r.teamReference.teamId.toLowerCase).map(_.friendlyName).result.headOption
        } yield (team2MemberRow, team)
      }
      val managerInsert = inputObject.managerOf.map(m => m.copy(teamReference = m.teamReference.copy(organizationId = apiRequest.parameters.organizationId))).map { r =>
        for {
          team2OwnerRow <- tables.Team2owners returning tables.Team2owners += Teams2OwnersEntity.fromEmtToTeam2owners(r, empRow.id)
          team <- tables.Teams.filter(_.id === r.teamReference.teamId.toLowerCase).map(_.friendlyName).result.headOption
        } yield (team2OwnerRow, team)
      }

      userInsert.flatMap { userRow =>
        val user = UserEntity.fromDbEntity(userRow)
        if (memberInsert.isDefined) memberInsert.get
          .map(r => user.copy(memberOf = Some(Teams2MembersEntity.fromEmtToMemberRef(r._1, r._2.map(TeamEntity.toApiFriendlyName).getOrElse(List.empty)))))
        else DBIO.successful(user)
        if (managerInsert.isDefined) managerInsert.get
          .map(r => user.copy(managerOf = Some(Teams2OwnersEntity.fromEmtToManagerRef(r._1, r._2.map(TeamEntity.toApiFriendlyName).getOrElse(List.empty)))))
        else DBIO.successful(user)
      }
    }

1 Ответ

0 голосов
/ 27 февраля 2020

Похоже, что запрос работает нормально, когда определен только memberInsert, когда я пытаюсь определить оба значения iememberInsert и managerInsert, тогда вставка происходит только для второго значения.

Проблема выглядит быть с последним вызовом flatMap.

Это должно вернуть DBIO[T]. Однако ваше выражение генерирует DBIO[T] в различных ветвях, но из flatMap будет возвращено только одно значение. Это объясняет, почему вы не видите все выполняемые действия.

Вместо этого вы можете назначить каждому шагу значение и упорядочить его. Есть множество способов сделать это , например, используя DBIO.seq или andThen.

Вот эскиз одного из подходов, который может работать для вас ....

val maybeInsertMemeber: Option[DBIO[User]] =
  member.map( your code for constructing an action here )

val maybeInsertManager Option[DBIO[User]] =
  manager.map( your code for constructing an action here )

DBIO.sequenceOption(maybeInsertMember) andThen
  DBIO.sequenceOption(maybeInsertManager) andThen
  DBIO.successful(user)

Результатом этого выражения является DBIO[User], который объединяет три запроса вместе.

...