RustでMySQLを操作してみる(読み込み)
RustでAPIサーバを作成するにあたり、MySQLを使いたいと思ったため どんな感じで使うことができるのか試してみました。
個人的には今までRailsで開発を行っていたこともあり、 ActiveRecordのようなORマッパーがよかったため、dieselを使用します。
http://diesel.rs/guides/getting-started/
環境
プロジェクト作成
ディレクトリ作成
mkdir diesel_demo cd diesel_demo
この中にdockerの準備していきます
docker
- docker/rust/Dockerfile
FROM rust:1.31 WORKDIR /diesel_demo RUN apt-get update -y && apt-get upgrade -y RUN apt-get install -y mysql-client RUN cargo install diesel_cli --no-default-features --features mysql
imageは公式が配布しているもの
https://hub.docker.com/_/rust/
docker内からMySQLを操作するため、mysql-clientをインストール
diesel_cliをインストールすることでスキーマ管理できます。
- docker-compose.yml
version: '2' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: password ports: - 3306:3306 volumes: - ./docker/mysql:/var/lib/mysql container_name: demo_sql rust: build: context: . dockerfile: ./docker/rust/Dockerfile environment: USER: root volumes: - ./:/diesel_demo depends_on: - db container_name: demo_rust
ここまで準備できたら以下を実行しプロジェクトを作成していきます。
docker-compose build docker-compose run --rm rust cargo init
生成されたCargo.tomlに以下を追記し、docker-compose run --rm rust cargo install
[dependencies] diesel = { version = "1.4.0", features = ["mysql"] } dotenv = "0.9.0
diesel_cliによるセットアップ
初めにdieselでMySQLに接続するために.env
を用意
echo DATABASE_URL=mysql://root:password@db/diesel_demo > .env
次に以下コマンドを実行します
docker-compose run --rm rust diesel setup
これでデータベースにdiesel_demoが作成されます
docker-compose run --rm rust diesel migration generate create_posts
上記コマンドで以下のファイルが生成されるのでそれぞれ記述していきます。
migrations/20160815133237_create_posts/up.sql
migrations/20160815133237_create_posts/down.sql
- up.sql
CREATE TABLE posts ( id INTEGER AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL, body TEXT NOT NULL, published BOOLEAN NOT NULL DEFAULT 0 ) DEFAULT CHARACTER SET= utf8mb4;
- down.sql
DROP TABLE posts
sqlファイルが書けたあと実行し、テーブル作成
docker-compose run --rm rust diesel migration run
作成したテーブルを削除するときはdiesel migration revert
でできる
DBの読み込み
以下のファイルを用意していきます 基本的にチュートリアルと変わらないため説明は省きます。 異なる部分としては、チュートリアルはPostgreSQLのため、 部分的にMySQLに書き換える必要があります。
- src/models.rs
#[derive(Queryable)] pub struct Post { pub id: i32, pub title: String, pub body: String, pub published: bool, }
- src/lib.rs
#[macro_use] extern crate diesel; extern crate dotenv; pub mod schema; pub mod models; use diesel::prelude::*; use dotenv::dotenv; use diesel::mysql::MysqlConnection; use std::env; pub fn establish_connection() -> MysqlConnection { dotenv().ok(); let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); MysqlConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url)) }
- src/bin/show_posts.rs
extern crate diesel_demo; extern crate diesel; use self::diesel_demo::*; use self::models::*; use self::diesel::prelude::*; fn main() { use diesel_demo::schema::posts::dsl::*; let connection = establish_connection(); let results = posts.filter(published.eq(true)) .limit(5) .load::<Post>(&connection) .expect("Error loading posts"); println!("Displaying {} posts", results.len()); for post in results { println!("{}", post.title); println!("-----------\n"); println!("{}", post.body); } }
実行する
サンプルデータをpostsテーブルに用意し、確認します。
insert into posts(title, body, published) values("test","おはよう",1); insert into posts(title, body, published) values("test2","こんにちは",0); insert into posts(title, body, published) values("test3","こんばんは",1); mysql> select * from posts; +----+-------+-----------------+-----------+ | id | title | body | published | +----+-------+-----------------+-----------+ | 1 | test | おはよう | 1 | | 2 | test2 | こんにちは | 0 | | 3 | test3 | こんばんは | 1 | +----+-------+-----------------+-----------+ 3 rows in set (0.01 sec)
docker-compose run --rm rust cargo run --bin show_posts => Displaying 2 posts test ----------- おはよう test3 ----------- こんばんは
実行結果を見るとpublished
がtrue(1)のものが表示されましたね。
これはposts.filter(published.eq(true))
でpublished
がtrueのものだけに絞り込んでいるからですね
この部分をfalseに置き換えるとpublished
が0のレコードが表示されます。
Displaying 1 posts test2 ----------- こんにちは
まとめ
diesel_cliでスキーマ管理が簡単にできますね!
今回は読み込みだけですがチュートリアルもあるので割と簡単にDB読み込みができました。