諸注意
- Rust超初心者です。お手柔らかにお願いします。
- いつもはpythonとC++を使うことが多いですが、Rust書いてみたかったので触ってみました。
- RustのORMについて何があるんだろうと調べて、どうやら「Diesel」とういうものがあると知り、使い勝手はどんなものか簡単に調べてみました。
やったこと
- gitにあるDieselのexampleコードを追いかけてみました。
- sqliteにdieselのマイグレーションでテーブルを作る。
- 手でサンプルデータをインサートする。
- diselからコネクションを作って、データの一覧を受け取る。
また、こちらdieselのサンプル(sqlite)を動かしてみたを参考にさせていただきました。素晴らしい記事をありがとうございます!!
##rustの環境
$ rustc --version
rustc 1.40.0-nightly (1423bec54 2019-11-05)
感想
- Dieselはそれに比べて少しドキュメントが少ないし、本家のgitのexampleもけっこうバグが出て悲しみが多い。(Dieselのexampleコード)
チュートリアルでバグが出るのはきついですよね、下のコードは下の環境下で動くことを確認済みなので、ぜひご活用ください!!
これからRust勉強していきます。
「いいね」や「コメント」お待ちしております!!
Diesel
いつものごとくプロジェクトを作ります。
cargo new web_diesel
Cargo.toml
[dependencies]
rocket="0.4"
rocket_contrib={version="0.4", features=["json"]}
serde = {version="1.0", features=["derive"]}
serde_json="1.0.0"
diesel = { version = "1.4.0", features = ["sqlite"] }
dotenv = "0.10"
データベースを作ります。
これでsample.dbというsqliteのファイルができます。
$ echo DATABASE_URL=./sample.db > .env
$ diesel setup
マイグレーションをします。
$ diesel migration generate create_posts
できたマイグレーションフォルダのup.sqlに
up.sql
CREATE TABLE posts (
id INTEGER NOT NULL PRIMARY KEY,
title VARCHAR NOT NULL,
body TEXT NOT NULL,
published BOOLEAN NOT NULL DEFAULT 0
)
down.sqlに
down.sql
DROP TABLE posts
と書く。
ここで、フォルダの中は
$ls
Cargo.lock Cargo.toml diesel.toml migrations/ sample.db src/ target/
tree src
src
├── main.rs
├── models.rs
├── sample.db
├── schema.rs
となっている。
main.rs
#[macro_use]
extern crate diesel;
use web_diesel::models::*;
use diesel::prelude::*;
#[macro_use]
extern crate dotenv;
// models.rsとschema.rsのインポート
pub mod models;
pub mod schema;
use diesel::prelude::*;
use dotenv::dotenv;
use std::env;
//Sqliteコネクションを作る。
pub fn establish_connection() -> SqliteConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
SqliteConnection::establish(&database_url)
.unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}
//レコードをすべて受け取る。
fn main() {
use web_diesel::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);
}
}
models.rs
#[derive(Queryable)]
pub struct Post {
pub id: i32,
pub title: String,
pub body: String,
pub published: bool,
}
schema.rs
table! {
posts (id) {
id -> Integer,
title -> Text,
body -> Text,
published -> Bool,
}
}
とりあえず、手でデータをインサートして、ORMで全件取得ということをしてみます。
$sqlite3 sample.db
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
sqlite> .table
__diesel_schema_migrations posts
sqlite> insert into posts values(1,"title1", "body1",0);
という感じで五件くらい入れてみます。
$sqlite3 sample.db
sqlite> select * from posts;
1|title1|body1|0
2|title2|body2|0
3|title3|body3|0
4|title4|body4|0
5|title5|body5|0
sqlite>
が確認できたら、
プロジェクトリポジトリ直下(sample.dbがある場所)で、
cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `target/debug/web_diesel`
Displaying 5 posts
title1
----------
body1
title2
----------
body2
title3
----------
body3
title4
----------
body4
title5
----------
body5
とレコードが取得できるのを確認できました。
後日もっといろいろやってみたいと思います!!