header source
my icon
esplo.net
ぷるぷるした直方体
Cover Image for diesel Memo

diesel Memo

about6mins to read

I've been using diesel for work, but sometimes I find it difficult to search for information in the documentation or realize how to implement certain features.
So, I'll write down what I've learned as I go along. I plan to add more content as I think of it.

Executing Raw SQL

diesel does not support window functions or subqueries.
Therefore, I've been implementing pagination by directly manipulating SQL.

http://diesel.rs/guides/extending-diesel/

Although it's good to write frequently used code in this way, it can be a hassle when you just want to get it working. That's why it's convenient to know how to handle raw SQL.

To execute raw SQL, you can use sql_query, which performs by-name mapping when loading.
The struct that performs the mapping should derive QueryableByName.

#[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 ....")

Associations

When retrieving related tables, you can use derive(Associations) and #[belongs_to(XXX)] on the struct, and then specify the ID using belonging_to.
This performs filtering using WHERE IN.

https://docs.diesel.rs/diesel/associations/index.html

SELECT * FROM hoge
WHERE IN (1,2,3....)

Therefore, the ID must be determined at the time of SQL execution, and subqueries cannot be used.
If you're concerned about performance due to the need to execute two queries, you can try using raw SQL.

Grouped By

Unlike SQL's group_by, grouped_by is a function that groups data that has already been loaded.
It links using foreign keys.
By zipping afterwards, you can get a structure that combines parent and child data arrays.
For more information, see below.

https://docs.diesel.rs/diesel/associations/trait.GroupedBy.html

Retrieving a Single Record

You can simply use find.
Load the struct with derive(Identifiable).

Select Restrictions when Using GROUP BY

There is a stronger constraint than MySQL 8.0's engine, where only columns that appear in GROUP BY can be specified in SELECT in the QueryBuilder.
Therefore, you need to write the following code using raw SQL (A and B have a 1:N relationship).

SELECT A.*
FROM B
LEFT JOIN A on B.a_id = A.id
GROUP BY B.A_id

https://github.com/diesel-rs/diesel/issues/772

Useful URLs

Conclusion

diesel is fun.
I'll add more content as I think of it.

Share