レコード更新する方法です。
環境は Postgres のバージョン 11 を使います。またその環境は Docker を用いて以下のコマンドで建てたサーバーを使います。
docker run \
--name postgres \
--detach \
--publish 5432:5432 \
--env POSTGRES_HOST_AUTH_METHOD=trust \
postgres:11
準備
Insert 時と同じ内容です。
Query 時と同じようにマイグレーションファイルを作り、いくつか適当なレコードが入ってる環境を作ります。
diesel migration generate create_users
作られたup.sql
とdown.sql
をそれぞれ以下のように編集します。
-- Your SQL goes here
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(30) NOT NULL
);
INSERT INTO users (name) VALUES
('foo'),
('bar');
-- This file should undo anything in `up.sql`
DROP TABLE IF EXISTS users;
以下のコマンドでデータを流し込んで完了です。
diesel migration run \
--database-url postgres://postgres:@localhost:5432
psql postgres://postgres:@localhost:5432 \
--tuples-only \
--command \
'select json_agg(users) from users' \
| tr -d '\n+' \
| jq .
[
{
"id": 1,
"name": "foo"
},
{
"id": 2,
"name": "bar"
}
]
src/schema.rs
ができているので、いつものsrc/lib.rs
を雛形の形にしておきます。
#[macro_use]
extern crate diesel;
pub mod schema;
プライマリーキーからデータを更新する
src/main.rs
を書いていきます。
まずはプライマリキーでレコードを直接を取得し、その値を更新する方法です。その場合diesel::update
関数を使います。
diesel::update
の引数には、table!
マクロで生成されるtable_name::dsl::table_name
構造体の.find
メソッドを対象のプライマリーキー値と共に使います。
更新後に期待する値は.set
メソッドを使います。table!
マクロはtable_name::dsl
以下にそのテーブルのカラム名の構造体を持ちます。その中から更新したいカラム構造体の.eq
メソッドを、期待する次の値と共に使い、.set
メソッドの引数とします。
use diesel::pg::PgConnection;
use diesel::prelude::*;
use get_started_diesel_insert::schema;
const DATABASE_URL: &'static str = "postgres://postgres:@localhost:5432";
fn main() {
let connection =
PgConnection::establish(DATABASE_URL).expect(&format!("Error connecting to {}", DATABASE_URL));
diesel::update(schema::users::dsl::users.find(1))
.set(schema::users::dsl::name.eq("baz"))
.execute(&connection)
.expect("Error saving new users");
}
条件に当てはまるレコードの値を更新
diesel::update
引数で使うtable_name
構造体で.eq
メソッドではなく.filter
を使います。その引数ではカラム名の構造体の.eq
を使い、「カラム値がこの値のもの」のようにします。
use diesel::pg::PgConnection;
use diesel::prelude::*;
use get_started_diesel_insert::schema;
const DATABASE_URL: &'static str = "postgres://postgres:@localhost:5432";
fn main() {
let connection =
PgConnection::establish(DATABASE_URL).expect(&format!("Error connecting to {}", DATABASE_URL));
let target = schema::users::dsl::users.filter(schema::users::dsl::name.eq("bar"));
diesel::update(target))
.set(schema::users::dsl::name.eq("baz"))
.execute(&connection)
.expect("Error updating an users");
}
すべてのレコードを更新
単にすべてを更新したければdiesel::update
の引数にそのままtable_name
構造体を渡すだけです。
diesel::update(schema::users::dsl::users))
.set(schema::users::dsl::name.eq("baz"))
.execute(&connection)
サンプルコード
動作確認できるコードは nju33-com/get-started-diesel-update に置かれています。