質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

Q&A

解決済

1回答

501閲覧

ScalaのSlickでメインデータに追加データを左結合する実装で追加データが無いケースの記述方法

ReiLeiLei1025

総合スコア236

Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

0グッド

0クリップ

投稿2021/04/27 12:00

お世話になっております。

ScalaのフレームワークAkkaでAPIサーバを作成しています。
DBライブラリにはSlickを使用しています。

現在運用中のコードに、新しいサービスを提供するために必要なテーブルを左結合させるSQLを記述しました。

そのSQLを実行した後のDB内データをgroupByする必要があります。
groupByするオブジェクトの型がSeq[Option[DB定義モデルクラス]]なため、値取得の際にはgetする必要があります。
コンパイラはfoundな型としてSeq[DB定義モデルクラス]と判別するようです。

DB定義モデルクラスの方をSeq[DB定義モデルクラス]にしたところ、想定通り動くようになりましたが、leftjoinするデータがない場合、サーバーエラーを返します。

コード内のtuples.map(_._3)の部分をflatMapにするなども試したのですが、foundされるものはうまく変換されるものの、requiredの方がコレクションを返すように変更されてしまい上手く動きません。

Error

1[error] found : (Option[DB定義モデルクラス], Option[DB定義モデルクラス2]) 2[error] required: scala.collection.GenTraversableOnce[?]

こういう場合はどう書くべきなのでしょうか。
教えて頂けると大変有り難いです。
よろしくお願い致します。

ロジック

Scala

1val query = for { 2 s ← exam1Table if s.id === id 3 v ← exam2Table if v.examId === s.id 4 } yield (s, v) 5 6val query2 = for { // 追加した部分 中間テーブル、追加した親テーブル、追加した親テーブルの子テーブル 欲しいのは追加した親テーブルと追加した親テーブルの子テーブルのみ 7 ((((t1, t2), t3), t4), t5) ← query.joinLeft(intermediateTable).on { case (k1, k2) ⇒ k1._1.id === k2.examId }.joinLeft(AddTable).on { case ((m1, m2), m3) ⇒ m2.map(_.addId === m3.id) }.joinLeft(addChildTable).on { case ((((n1, n2), n3), n4), n5) ⇒ n4.map(_.id === n5.parentId) } 8 } yield (t1,t2,(t4,t5))) 9 10for { 11 tuples ← query2.result 12 } yield tuples.headOption.map { 13 case (s,v,_)⇒ SampleDbClass( 14 s.id, 15 v.exam_name, 16 tuples.map(_._3).groupBy(_._1.get.id).values.map { xs ⇒  17 val var_sa = xs.map(_._1).head.get 18 ... val addChild = addChildクラスの定義 ... 19 DeployAddClass(var_sa.id, addChild) 20 }.toSeq 21 ) 22 }

DB定義モデルクラス

Scala

1case class SampleDbClass( 2 id: SampleDbClass.Id, 3 exam2_name: String, 4 DeployAddDbClasses: Seq[Option[DeployAddClass]] 5) 6 7case class AddClass( 8 id: AddClass.Id, 9) 10 11case class DeployAddClass( //AddClassをサービスに合わせるように表示出来るように拡張 12 id: AddClass.Id, 13 addChilds: Seq[Option[AddChildClass]] 14) 15 16case class AddChildClass( 17 id: AddChildClass.Id, 18 parentId: AddClass.Id 19) 20

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

下のようにPlainSQLを実行してasでクラスにマッピングするような書き方をしてみてはどうですか?

Scala

1sql""" 2 select ADDRESS_ID, AVG(AGE) 3 from PERSON 4 group by ADDRESS_ID 5""".as[(Int,Option[Int])]

slick-doc-ja 3.0 — SQLからSlickを利用する人へ

投稿2021/05/11 14:39

rysh

総合スコア874

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ReiLeiLei1025

2021/05/12 04:08

こういう形で値の取得が出来るのですね。 直感的で理解しやすい記述方法ですね。 ありがとうございます。 参考にいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問