dieselのメモ
所用でdieselを使っているのですが、ドキュメントから探すのが難しかったり、実現できなかったりすることがパッと分からなかったりします。 ということで、本記事は触ってみて気づいたことを書き溜めておくチラ裏です。気が向いたときに追記してゆく予定です。
生SQLの実行
dieselではwindow関数やsubqueryをサポートしていません。 そのため、paginationはsqlを直にいじることで実現しています。
頻繁に使う記述はこのように作ると良いのですが、とりあえず動かしたい場合にはなかなか手間です。ということで、生SQLを扱う方法を覚えておくと便利です。
生SQLの実行にはsql_queryを使うと、load時にby-nameでマッピングを行ってくれます。 マッピングする先のstructでは、QueryableByNameをderiveしておきます。
#[derive(QueryableByName, Serialize, Debug)] pub struct LastUpdate { #[sql_type = "Datetime"] pub dt: chrono::NaiveDateTime, }
use diesel::sql_query; use diesel::sql_types::Integer; sql_query( r#" SELECT x.*, updated_at as dt FROM hoge LIMIT ? "# ) .bind::<Integer, _>(5) .load::<(Hoge, Rank)>(&*conn) .expect("cannot execute ....")
association
関連するテーブルを引っ張ってくる場合は、structにderive(Associations)
と#[belongs_to(XXX)]
を付けてbelonging_to
でIDを指定して取得できます。
これはWHERE IN
による絞り込みが行われます。
SELECT * FROM hoge WHERE IN (1,2,3....)
そのため、IDが該当SQLの実行時に決まっている必要があり、subqueryでは実行できません。 2度クエリを実行するため、パフォーマンスが気になる場合は生SQLなどで頑張りましょう。
grouped_by
SQLのgroup_by
とは異なり、既にloadしたデータをグルーピングする関数がgrouped_by
です。
外部キーでくっつきます。
この後にzipすることで、親データと小データの配列をセットにした構造が得られます。
詳しくは↓で。
1件取得
普通にfind
が使えます。
derive(Identifiable)
を付けたstructでloadすること。
GROUP BYした際のselect制限
QueryBuilderにはGROUP BYに現れたカラムのみSELECTで指定できるという、MySQL 8.0のエンジンより強い制約があります。 そのため、下記のような記述は生SQLで書く必要があります(AとBは1:多対応)。
SELECT A.* FROM B LEFT JOIN A on B.a_id = A.id GROUP BY B.A_id
便利なURLたち
- diesel-rs/diesel - Github: 公式
- Crate diesel: APIが気になった時に。
- Diesel Tag - κeenのHappy Hacκing Blog: いつもお世話になっております。
- 仕事でdiesel使ってみた: ↑から漏れていたので
まとめ
diesel楽しい。 気づいたことがあれば追記してゆきます。