レコード更新する方法です。
環境は 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 に置かれています。