0Pricing
Learn Rust Coding · レッスン

コンパイル時に検査されるクエリ

型安全なSQL

「コンパイル時に検査されるクエリ」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。

決め手となる機能

sqlxは実際のデータベーススキーマに対して、SQLをコンパイル時に検証できます。タイプミス、誤ったカラム名、型の不一致をビルドエラーとして検出できます。

  • query!ファミリーのマクロを使用します
  • 実行時より前にバグを検出できます

query!とqueryの違い

query()関数は実行時にチェックされます。query!マクロは、ビルド中にデータベースへ接続することでコンパイル時にチェックされます。

use sqlx::{Pool, Postgres};

async fn run(pool: &Pool<Postgres>) {
    let rec = sqlx::query!("SELECT id, name FROM users WHERE id = $1", 1i32)
        .fetch_one(pool)
        .await
        .unwrap();
}

型付きの結果フィールド

query!マクロは、選択したカラムに対応するフィールドを持つ匿名構造体を生成し、スキーマから正しいRustの型を推論します。

use sqlx::{Pool, Postgres};

async fn name_of(pool: &Pool<Postgres>, id: i32) -> String {
    let rec = sqlx::query!("SELECT name FROM users WHERE id = $1", id)
        .fetch_one(pool)
        .await
        .unwrap();
    rec.name
}

チェックの仕組み

ビルド時にsqlxは、稼働中のDATABASE_URLまたはキャッシュ済みの.sqlxディレクトリを必要とします。クエリをDBに送信し、パラメーターと結果の型を確認します。

cargo sqlx prepareによるオフラインモード

データベースを利用できないCIでは、cargo sqlx prepareを実行してクエリのメタデータを.sqlx/に保存します。その後のビルドではキャッシュが使われます。

cargo sqlx prepare

query_as!で構造体に変換する

query_as!を使うと、行を定義した構造体へ直接マッピングできます。チェックも完全に行われます。

use sqlx::{Pool, Postgres};

struct User { id: i32, name: String }

async fn get(pool: &Pool<Postgres>) -> User {
    sqlx::query_as!(User, "SELECT id, name FROM users WHERE id = $1", 1i32)
        .fetch_one(pool)
        .await
        .unwrap()
}

NULL可能なカラムはOptionになる

カラムがNULLになる可能性がある場合、sqlxはフィールドをOptionにします。name as "name!"のような型アノテーションで推論を上書きできます。

use sqlx::{Pool, Postgres};

async fn maybe_email(pool: &Pool<Postgres>) -> Option<String> {
    let rec = sqlx::query!("SELECT email FROM users WHERE id = $1", 1i32)
        .fetch_one(pool)
        .await
        .unwrap();
    rec.email
}

型推論のモデル化

コンパイル時チェックでは、SQLの型をRustの型に対応付けます。この実行可能な例では、その対応付けの判断をモデル化しています。

fn rust_type(sql: &str, nullable: bool) -> String {
    let base = match sql {
        "int4" => "i32",
        "text" => "String",
        "bool" => "bool",
        _ => "unknown",
    };
    if nullable { format!("Option<{}>", base) } else { base.to_string() }
}

fn main() {
    println!("{}", rust_type("int4", false));
    println!("{}", rust_type("text", true));
}

表示されるコンパイルエラー

存在しないカラムを参照すると、sqlxは明確なメッセージを表示してビルドに失敗します。この安全性こそがマクロを使う目的です。

  • 誤ったカラム名 → コンパイル時エラー
  • 型の不一致 → コンパイル時エラー

バインドパラメーターは位置指定

Postgresでは$1、$2のプレースホルダーを使います。sqlxは、バインドする各引数の型をスキーマと照合します。

use sqlx::{Pool, Postgres};

async fn search(pool: &Pool<Postgres>, name: &str, min_age: i32) {
    let _ = sqlx::query!(
        "SELECT id FROM users WHERE name = $1 AND age >= $2",
        name, min_age
    ).fetch_all(pool).await.unwrap();
}

マクロを使わない形式を使用する場合

実行時に構築する動的SQL(事前にカラムが分からない場合)には、query() / query_as()を使います。柔軟性を得る代わりに、コンパイル時チェックを失います。

use sqlx::{Pool, Postgres};

async fn dynamic(pool: &Pool<Postgres>, sql: &str) {
    let _ = sqlx::query(sql).execute(pool).await.unwrap();
}

理解度チェック

コンパイル時チェックについての理解度を確認しましょう。

まとめ

コンパイル時にチェックされるクエリについて学びました。

  • query!とquery_as!は、ビルド時にスキーマに対してSQLを検証します
  • 結果のフィールドと型は自動的に推論されます
  • NULL可能なカラムはOptionになります
  • cargo sqlx prepareでオフラインビルドが可能になります
  • 動的SQLにはマクロを使わないquery()を使用します

次はCRUD操作です。

よくある質問

「コンパイル時に検査されるクエリ」レッスンは無料ですか?

はい。「コンパイル時に検査されるクエリ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。

「コンパイル時に検査されるクエリ」で何を学びますか?

型安全なSQL ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn Rust Codingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「コンパイル時に検査されるクエリ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn Rust Codingレッスンでコードを書いて実行できますか?

はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. データベースへの接続
  2. コンパイル時に検査されるクエリ
  3. CRUD操作
  4. マイグレーション
← Learn Rust Codingに戻る