Postgres を使う
Postgres データベースにテーブルを作成する
Postgres データベースにテーブルを作成するには postgres クレートを使用します。
Client::connect は既存のデータベースへの接続に役立ちます。このレシピでは、Client::connect で URL 文字列形式を使用しています。既存の library という名前のデータベースがあり、ユーザー名が postgres、パスワードが postgres であることを前提としています。
use postgres::{Client, NoTls, Error};
fn main() -> Result<(), Error> {
let mut client = Client::connect("postgresql://postgres:postgres@localhost/library", NoTls)?;
client.batch_execute("
CREATE TABLE IF NOT EXISTS author (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
country VARCHAR NOT NULL
)
")?;
client.batch_execute("
CREATE TABLE IF NOT EXISTS book (
id SERIAL PRIMARY KEY,
title VARCHAR NOT NULL,
author_id INTEGER NOT NULL REFERENCES author
)
")?;
Ok(())
}
データの挿入とクエリ
このレシピでは、Client の execute メソッドを使用して author テーブルにデータを挿入します。次に、Client の query メソッドを使用して author テーブルのデータを表示します。
use postgres::{Client, NoTls, Error};
use std::collections::HashMap;
struct Author {
_id: i32,
name: String,
country: String
}
fn main() -> Result<(), Error> {
let mut client = Client::connect("postgresql://postgres:postgres@localhost/library",
NoTls)?;
let mut authors = HashMap::new();
authors.insert(String::from("Chinua Achebe"), "Nigeria");
authors.insert(String::from("Rabindranath Tagore"), "India");
authors.insert(String::from("Anita Nair"), "India");
for (key, value) in &authors {
let author = Author {
_id: 0,
name: key.to_string(),
country: value.to_string()
};
client.execute(
"INSERT INTO author (name, country) VALUES ($1, $2)",
&[&author.name, &author.country],
)?;
}
for row in client.query("SELECT id, name, country FROM author", &[])? {
let author = Author {
_id: row.get(0),
name: row.get(1),
country: row.get(2),
};
println!("Author {} is from {}", author.name, author.country);
}
Ok(())
}
集計データ
このレシピは、Museum of Modern Art のデータベースに登録されている最初の 7999 人のアーティストの国籍を降順で一覧表示します。
use postgres::{Client, Error, NoTls};
struct Nation {
nationality: String,
count: i64,
}
fn main() -> Result<(), Error> {
let mut client = Client::connect(
"postgresql://postgres:postgres@127.0.0.1/moma",
NoTls,
)?;
for row in client.query
("SELECT nationality, COUNT(nationality) AS count
FROM artists GROUP BY nationality ORDER BY count DESC", &[])? {
let (nationality, count) : (Option<String>, Option<i64>)
= (row.get (0), row.get (1));
if nationality.is_some () && count.is_some () {
let nation = Nation {
nationality: nationality.unwrap(),
count: count.unwrap(),
};
println!("{} {}", nation.nationality, nation.count);
}
}
Ok(())
}