LoginSignup
0
0

More than 3 years have passed since last update.

RustのDieselでPostgresのMACADDR型を使う

Last updated at Posted at 2021-03-18

はじめに

最近、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
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0