Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@Yukimura127

RustのDieselでPostgresのMACADDR型を使う

はじめに

最近、RustのDieselを使い始めました。
DieselはPostgres/MySQL/SQLiteに接続することができます。
今回、PostgresのMACADDR型を使う際に躓いたので、解決策を備忘録的に残しておきます。

困ったこと

以下のようにMACADDRを使うスキーマとモデルを定義しました。

up.sql
CREATE TABLE machines (
  id SERIAL PRIMARY KEY,
  name VARCHAR(20) NOT NULL,
  mac_address MACADDR NOT NULL,
  status_id INTEGER NOT NULL,
  create_at timestamptz NOT NULL DEFAULT current_timestamp,
  update_at timestamptz NOT NULL DEFAULT current_timestamp
);
model.rs
#[derive(Debug, Queryable)]
pub struct Machine {
    pub id: i32,
    pub name: String,
    pub mac_address: [u8; 6],
    pub status_id: i32,
    pub create_at: chrono::NaiveDateTime,
    pub update_at: chrono::NaiveDateTime,
}

全件SELECTする処理を書いて実行すると...

let machines = machines_schema::dsl::machines
    .load::<Machine>(&connection)
    .expect("Error loading machines");
for machine in &machines {
    println!("{:?}", machine);
}
$ cargo run
・
・
error[E0277]: the trait bound `[u8; 6]: Queryable<MacAddr, Pg>` is not satisfied
  --> src/main.rs:66:10
   |
66 |         .load::<Machine>(&connection)
   |          ^^^^ the trait `Queryable<MacAddr, Pg>` is not implemented for `[u8; 6]`

モデルにパースする際、MACADDRを[u8; 6]に変換する実装がない、というエラーです。
Referenceを見ると[u8; 6]への変換で正しそうです。

解決策

RustのDieselはfeaturesを指定することで使えるようになる機能があります。
例えば、timestamp等の時間に関わるものであれば「chrono」を追加する必要があります。

Cargo.toml



[dependencies]
diesel = { version = "1.4.6", features = ["postgres", "chrono"], default-features = false }

ネットワーク系も同様にfeatures「network-address」を追加する必要がありました。
(DieselのGitHubのCargo.tomlに一覧があるのでここから探しました...)

Cargo.toml



[dependencies]
diesel = { version = "1.4.6", features = ["postgres", "chrono", "network-address"], default-features = false }

これでもう1度動作させると、無事SELECTできました。

Machine { id: 1, name: "machineC", mac_address: [82, 66, 0, 26, 169, 68], status_id: 1, create_at: 2021-03-18T14:01:48.632112, update_at: 2021-03-18T14:01:48.632112 }
Machine { id: 3, name: "machineA", mac_address: [82, 66, 0, 26, 169, 68], status_id: 1, create_at: 2021-03-18T14:53:06.281686, update_at: 2021-03-18T14:53:06.281686 }
Machine { id: 4, name: "machineB", mac_address: [82, 66, 0, 26, 169, 69], status_id: 1, create_at: 2021-03-18T14:53:06.281686, update_at: 2021-03-18T14:53:06.281686 }

まとめ

Dieselで「~ is not implemented for ~」というエラーが出た際はfeaturesを確認してみると良いよというお話でした。
機能を選択させることでCrateを軽くする設計でしょうね(必要なものだけ選択する)。

PS)
この記事を書く際にReferenceを見ていたら、先頭に「The MACADDR SQL type. This type can only be used with feature = "network-address"」と記載がありました...
Referenceはちゃんと読まないとだめですね。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What is going on with this article?