dieselのメモ
Table of Contents
所用で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楽しい。
気づいたことがあれば追記してゆきます。