0
0

【MySQL x RUST 】MySQL の DateTime 型を Rust の NaiveDateTime 型として抜き出す

Posted at

Hi, there! Rust が大好き SAmmys だよ!

今日はタイトルの通り、MySQLにDateTime型で格納されている情報をRustでNaiveDateTime形で取り出す内容だよ。
・・・え、それだけ?の内容だけど備忘録として残しておくよ。

前提として、データを取り出す元のテーブルは以下のように作成したんだ。

SQL
CREATE TABLE files (
    created_at DATETIME,
    prefix VARCHAR(255),
    name VARCHAR(255),
    INDEX idx_created_at (created_at)
);

そして、RUSTのプログラム本体は以下。(sqlxクレートを使ってるよ)

main.rs
…(前略)…

let query_result = sqlx::query_as!(
    FileInfo,
    "SELECT * FROM files WHERE name = ?",
    file_name
).fetch_one(&data.db).await;

そして、ここで使用しているFileInfoのStructは以下の通り。

models.rs
use chrono::{prelude::*, naive::NaiveDate};
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Default)]
pub struct FileInfo {
    pub created_at: NaiveDateTime,
    pub prefix: String,
    pub name: String,
}

そしたらね、エラーとしてこういった内容うが出てきたのさ。

ビルドエラー時のログ
error[E0277]: the trait bound `NaiveDate: std::convert::From<std::option::Option<NaiveDateTime>>` is not satisfied
   --> src/handler.rs:390:40
    |
390 |                       let query_result = sqlx::query_as!(
    |  ________________________________________^
391 | |                         FileInfo,
392 | |                         "SELECT * FROM files WHERE name = ?",
393 | |                         filename
394 | |                     )
    | |_____________________^ the trait `std::convert::From<std::option::Option<NaiveDateTime>>` is not implemented for `NaiveDate`
    |
    = help: the trait `std::convert::From<NaiveDateTime>` is implemented for `NaiveDate`
    = note: required for `std::option::Option<NaiveDateTime>` to implement `Into<NaiveDate>`
    = note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)

Rustからしたら、
「DB に null が入ってるかもしれないんだから、Option<> 付けて null の対応に備えておけよ!」
ってことなんだね。

結局、Struct の宣言を以下に修正すれば終了だったよ、って話。

models.rs
use chrono::{prelude::*, naive::NaiveDate};
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Default)]
pub struct FileInfo {
    pub created_at: Option<NaiveDateTime>,
    pub prefix: Option<String>,
    pub name: Option<String>,
}

今回のとは話が逸れるけど、REST API でクライアントからマルチパートアップロードで受け取ったバイナリデータを 6MB ごとにプールさせて AWS の S3 にマルチパートアップロードすることもできたよ。
つまり、メモリが 1 GB のマシンに REST APIサーバーを格納していても、例えば 20 GB のファイルを REST API を経由して S3にマルチパートアップロードアップロードできる、ってことね💡
こういう低レイヤーの制御ができるRust、本当に大好き💛
それでいてメモリも安全💛
それでいて処理も高速💛

あー大好きRust!!!

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