2021/10/24

Rust dieselでpostgresqlのjson型を使う

rustpostgresql

postgresqlのjson型のフィールドが含まれるテーブルに対して、rust dieselを使ってselectしたりinsertしたりを試してみました。

想像していたより簡単にできました。

やり方

  • serde_jsonをインストールする
  • serde_jsonfeaturesdieselに追加する
  • QueryableInsertableを実装している構造体のjson対応のフィールドにはserde_json::Valueを利用する
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
diesel = { version = "1.4.8", features = ["postgres", "chrono", "r2d2", "serde_json"] }

今回試した例

nullableなjsonフィールドを2つ持つ(request_dataresponse_data)テーブルを用意しました。

CREATE TABLE webhook_events (
    id serial primary key,
    event_type character varying(55) NOT NULL,
    request_data json,
    response_data json,
    status character varying(55) NOT NULL,
    created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);

sheme.rs

table! {
    webhook_events (id) {
        id -> Int4,
        event_type -> Varchar,
        request_data -> Nullable<Json>,
        response_data -> Nullable<Json>,
        status -> Varchar,
        created_at -> Timestamp,
    }
}

entity定義(DTO)

use crate::scheme::webhook_events;
use chrono::NaiveDateTime;
use serde_json;

#[derive(Queryable, Debug)]
pub struct WebhookEvent {
    pub id: i32,
    pub event_type: String,
    pub request_data: Option<serde_json::Value>,
    pub response_data: Option<serde_json::Value>,
    pub status: String,
    pub created_at: NaiveDateTime,
}

#[derive(Insertable, Debug)]
#[table_name = "webhook_events"]
pub struct NewWebhookEvent<'a> {
    pub event_type: &'a str,
    pub request_data: Option<serde_json::Value>,
    pub response_data: Option<serde_json::Value>,
    pub status: &'a str,
}

こちらで、selectやinsertが普通にできることが確認できました。

以上になります。