データを更新する。
成果物
コード
前回のコードを修正・追記する。
schema.rs
table! { posts (id) { id -> Integer, title -> Text, body -> Text, is_published -> Bool, } }
id
の型をNullable<Integer>
からInteger
へis_published
の型をText
からBool
へ
src/bin/publish_post.rs
新規作成する。
extern crate diesel; extern crate diesel_hello; use self::diesel::prelude::*; use self::diesel_hello::*; use std::env::args; fn main() { use diesel_hello::schema::posts::dsl::{posts, is_published}; let id = args() .nth(1) .expect("publish_post requires a post id") .parse::<i32>() .expect("Invalid ID"); let connection = establish_connection(); let _ = diesel::update(posts.find(id)) .set(is_published.eq(true)) .execute(&connection) .unwrap_or_else(|_| panic!("Unable to find post {}", id)); let post: models::Post = posts .find(id) .first(&connection) .unwrap_or_else(|_| panic!("Unable to find post {}", id)); println!("Published post {}", post.title); }
確認
$ sqlite3 ./db.sqlite3 SQLite version 3.22.0 2018-01-22 18:45:57 Enter ".help" for usage hints. sqlite> select * from posts; 1|記事のタイトル|記事の本文。 複数行を書く。 Ctrl+dキーで終了。 最終行。 |f
is_published
列の値がf
である。
実行
$ cargo run --bin publish_post 1 ... Published post 記事のタイトル
これで公開フラグを立てた。DBファイルを確認してみる。
$ sqlite3 /tmp/work/Rust.Diesel.20190727130150/src/2/diesel_hello/db.sqlite3 SQLite version 3.22.0 2018-01-22 18:45:57 Enter ".help" for usage hints. sqlite> select * from posts; 1|記事のタイトル|記事の本文。 複数行を書く。 Ctrl+dキーで終了。 最終行。 |1
f
が1
になった。
てっきりt
だと思ったのだが。なら初期値はf
でなく0
のほうが良さそう。まあいいか。
NG集
失敗1
失敗1
公式getting startedページのコードを使ったがダメだった。
src/bin/publish_post.rs
extern crate diesel_demo; extern crate diesel; use self::diesel::prelude::*; use self::diesel_demo::*; use self::models::Post; use std::env::args; fn main() { use diesel_demo::schema::posts::dsl::{posts, published}; let id = args().nth(1).expect("publish_post requires a post id") .parse::<i32>().expect("Invalid ID"); let connection = establish_connection(); let post = diesel::update(posts.find(id)) .set(is_published.eq(true)) .get_result::<Post>(&connection) .expect(&format!("Unable to find post {}", id)); println!("Published post {}", post.title); }
ポイントはupdate()
。is_published
フラグをfalse
からtrue
に変更する。
既存DB確認
$ sqlite3 ./db.sqlite3 SQLite version 3.22.0 2018-01-22 18:45:57 Enter ".help" for usage hints. sqlite> select * from posts; 1|記事のタイトル|記事の本文。 複数行を書く。 Ctrl+dキーで終了。 最終行。 |f
- 既存データは
f
(false
)である id
は1
である
実行
cargo run --bin publish_post 1
error[E0277]: the trait bound `bool: diesel::Expression` is not satisfied --> src/bin/publish_post.rs:17:27 | 17 | .set(is_published.eq(true)) | ^^ the trait `diesel::Expression` is not implemented for `bool` | = note: required because of the requirements on the impl of `diesel::expression::AsExpression<diesel::sql_types::Text>` for `bool`
前回、IDが1のレコードを追加した。ので、引数に1
を渡す。
失敗2
失敗2
githubのコードを使った。これが成功コードの元になった。
src/bin/publish_post.rs
extern crate diesel; extern crate diesel_hello; use self::diesel::prelude::*; use self::diesel_hello::*; use std::env::args; fn main() { use diesel_demo_step_3_sqlite::schema::posts::dsl::{posts, is_published}; let id = args() .nth(1) .expect("publish_post requires a post id") .parse::<i32>() .expect("Invalid ID"); let connection = establish_connection(); let _ = diesel::update(posts.find(id)) .set(is_published.eq(true)) .execute(&connection) .unwrap_or_else(|_| panic!("Unable to find post {}", id)); let post: models::Post = posts .find(id) .first(&connection) .unwrap_or_else(|_| panic!("Unable to find post {}", id)); println!("Published post {}", post.title); }
error[E0277]: the trait bound `bool: diesel::Expression` is not satisfied --> src/bin/publish_post.rs:19:27 | 19 | .set(is_published.eq(true)) | ^^ the trait `diesel::Expression` is not implemented for `bool` | = note: required because of the requirements on the impl of `diesel::expression::AsExpression<diesel::sql_types::Text>` for `bool`
schema.rsをみてみると、is_published -> Bool,
となっていた。対して私のコードはText
。
schema.rs
table! { posts (id) { id -> Nullable<Integer>, title -> Text, body -> Text, is_published -> Text, } }
is_published -> Bool,
となっていた。is_published
のText
をBool
に修正して再度コンパイルする。
またエラー。
error[E0277]: the trait bound `i32: diesel::deserialize::FromSql<diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sqlite::Sqlite>` is not satisfied --> src/bin/publish_post.rs:25:10 | 25 | .first(&connection) | ^^^^^ the trait `diesel::deserialize::FromSql<diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sqlite::Sqlite>` is not implemented for `i32` | = help: the following implementations were found: <i32 as diesel::deserialize::FromSql<diesel::sql_types::Integer, DB>> <i32 as diesel::deserialize::FromSql<diesel::sql_types::Integer, diesel::sqlite::Sqlite>> = note: required because of the requirements on the impl of `diesel::Queryable<diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sqlite::Sqlite>` for `i32` = note: required because of the requirements on the impl of `diesel::Queryable<(diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sql_types::Text, diesel::sql_types::Text, diesel::sql_types::Bool), diesel::sqlite::Sqlite>` for `(i32, std::string::String, std::string::String, bool)` = note: required because of the requirements on the impl of `diesel::Queryable<(diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sql_types::Text, diesel::sql_types::Text, diesel::sql_types::Bool), diesel::sqlite::Sqlite>` for `diesel_hello::models::Post` = note: required because of the requirements on the impl of `diesel::query_dsl::LoadQuery<diesel::SqliteConnection, diesel_hello::models::Post>` for `diesel::query_builder::SelectStatement<diesel_hello::schema::posts::table, diesel::query_builder::select_clause::DefaultSelectClause, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<diesel::expression::operators::Eq<diesel_hello::schema::posts::id, diesel::expression::bound::Bound<diesel::sql_types::Nullable<diesel::sql_types::Integer>, i32>>>, diesel::query_builder::order_clause::NoOrderClause, diesel::query_builder::limit_clause::LimitClause<diesel::expression::bound::Bound<diesel::sql_types::BigInt, i64>>>`
schema.rsを見比べてみると、id -> Integer,
だった。対して私の環境は以下。
table! { posts (id) { id -> Nullable<Integer>, title -> Text, body -> Text, is_published -> Bool, } }
Nullable
という余計なものがついている。これを取り去りInteger
にして再実行。
成功!
$ cargo run --bin publish_post 1 ... Published post 記事のタイトル
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
- rustc 1.36.0 (a53f9df32 2019-07-03)
- cargo 1.36.0 (c4fcfb725 2019-05-15)
$ uname -a Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux
前回まで
- Rust学習まとめ(ドキュメント)
- Rust自習(じゃんけんゲーム1)
- Rust自習(双方向リスト1)
- Rust自習(単方向リスト1)
- Rust自習(単方向リスト2)
- Rust自習(単方向リスト3)
- Rust自習(単方向リスト4)
- Rust自習(単方向リスト5)
- Rust自習(単方向リスト6)
- Rust自習(単方向リスト7)
- Rust自習(リストのインタフェースを考える)
- Rust自習(連結リスト1)
- Rust自習(連結リスト2)
- Rust自習(連結リスト3)
- Rust自習(連結リスト4)
- Rust自習(連結リストの取得系インタフェース考察)
- Rust自習(連結リスト5)
- Rust自習(連結リストの取得系インタフェース考察2)
- Rust自習(連結リスト6)
- Rust自習(連結リスト7)
- Rust自習(連結リスト8)
- Rust自習(連結リスト9)
- Rust自習(変数名でイテレートする方法)
- Rust自習(iter、iter_mut実装方法)
- Rust自習(連結リスト10)
- Rust自習(rev()実装できず)
- Rust自習(cycle()実装できず)
- Rust自習(じゃんけんゲーム2)
- Rust自習(じゃんけんゲーム3)
- Rust自習(じゃんけんゲーム4)
- Rust自習(じゃんけんゲーム5)
- Rust自習(じゃんけんゲーム6)
- Rust自習(じゃんけんゲーム7)
- Rust自習(じゃんけんゲーム8)
- Rustのアップデート(rustup update)
- Rust自習(SQLite3 1)
- Rust自習(SQLite3 2)
- Rust自習(SQLite3 3)
- Rust自習(日時 1 chrono)
- Rust自習(日時 2 chrono)
- Rust自習(日時 3 chrono)
- Rust自習(日時 4 chrono)
- Rust自習(日時 5 chrono)
- Rust自習(日時 6 chrono)
- Rust自習(日時 7 chrono)
- Rust自習(std::time::SystemTime)
- Rust自習(std::time::Instant)
- Rust自習(std::time::Duration)
- Rust自習(シリアライズ serde 1)
- JSON5とは?
- Rust自習(シリアライズ serde 2 JSON5)
- Rust自習(シリアライズ serde 3 chrono日時型変換)
- Rust自習(diesel 1 SQLite3 ORM)
- Rust自習(diesel 2 SQLite3 ORM)