【Rust】如何使用Rust + PostgreSQL + tokio_postgres访问数据库

它很轻松自在

我想要做的事情

我們可以使用Rust快速且輕鬆地與本地PostgreSQL進行集成,並在Rust端操作和建立這樣的表格。

     id      |   name   
-------------+----------
  -838073477 | John Doe
 -1966422589 | John Doe
 -2115227795 | John Doe
(3 rows)
id和name并没有特别深的意义,只是随意填入了一些示例值。

在Rust中,使用标准输入

標準入力機能a乱数のidと名前(今回はJohn Doe固定)をrecordというdbに追加sテーブルを全表示dテーブルを全削除

我们加入了类似的功能。

行动环境 zuò

項目値OSUbuntu22.04 On WSL2Rust1.70.0psql (PostgreSQL)15.3

潮水涌动

    1. 使用PostgreSQL创建一个名为record的空数据库

 

    1. 使用Rust编写程序

 

    1. 在Rust端输入a, s, d等内容来操作record

 

    在PostgreSQL端确认表格

那么,就分别讨论每个项目。

在PostgreSQL中创建一个空数据库(名称为record)。

1. 需要进行预装等准备工作的内容

sudo apt update
sudo apt install postgresql
sudo systemctl status postgresql

打开终端并切换到postgres用户。

sudo -u postgres psql

3. 创建账户和记录数据库

CREATE USER your_username WITH PASSWORD 'your_password';
CREATE DATABASE record;
请自行设置您的用户名和密码。
如果您想要更改数据库的名称,请将记录替换为任意的名称。

为用户”你的用户名”授予权限

GRANT ALL PRIVILEGES ON DATABASE type_record TO your_username;
GRANT ALL PRIVILEGES ON SCHEMA public TO your_username;

请注意在数据库和模式中都授予访问权限
(我只赋予了数据库的权限,之后遇到了约2个小时的问题)

使用Rust进行程序编写。

1. 在dependencies中添加一个crate

[dependencies]
+ tokio-postgres = "0.7"
+ tokio = { version = "1", features = ["full"] }
+ dotenv = "0.15.0"
+ rand = "0.8.4"

在.env文件中添加内容

+ DB_HOST=localhost
+ DB_PORT=5432
+ DB_USER=your_username
+ DB_PASSWORD=your_password
+ DB_NAME=record
你的用户名和密码与在创建账户和记录数据库时所创建的相同。

如果没有.env文件,您可以返回到使用Rust进行操作的目录的根目录。

code .env

请使用「等」为我创作。

3. 以Rust语言进行实现

下面是一个示例。
我加入了适当的评论。

use dotenv::dotenv;
use std::env;
use std::io::{self, BufRead};
use tokio_postgres::{NoTls, Error};
use rand::Rng;

#[tokio::main]
async fn main() -> Result<(), Error> {
    // .env ファイルを読み込み
    dotenv().ok();

    // 環境変数から接続情報を取得
    let db_host = env::var("DB_HOST").expect("DB_HOST not set");
    let db_port = env::var("DB_PORT").expect("DB_PORT not set");
    let db_user = env::var("DB_USER").expect("DB_USER not set");
    let db_password = env::var("DB_PASSWORD").expect("DB_PASSWORD not set");
    let db_name = env::var("DB_NAME").expect("DB_NAME not set");

    // PostgreSQLの接続情報を設定
    let connection_string = format!(
        "host={} port={} user={} password={} dbname={}",
        db_host, db_port, db_user, db_password, db_name
    );

    let (client, connection) = tokio_postgres::connect(&connection_string, NoTls).await?;

    // 接続タスクをスポーンして実行
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("connection error: {}", e);
        }
    });

    // テーブル作成のクエリを実行
    client
        .batch_execute(
            "
            CREATE TABLE IF NOT EXISTS users (
                id SERIAL PRIMARY KEY,
                name TEXT NOT NULL
            )
            ",
        )
        .await?;

    // 標準入力からキー入力を受け取るためのストリームを作成
    let stdin = io::stdin();
    let mut input_stream = stdin.lock().lines();

    println!("Press 'a' to add a record, 'd' to delete all records, 's' to sort and display records, or any other key to exit.");

    // キー入力を監視し、対応する操作を実行
    while let Some(Ok(input)) = input_stream.next() {
        match input.as_str() {
            "a" => {
                // レコードの追加
                let mut rng = rand::thread_rng();
                let id: i32 = rng.gen();

                client
                    .execute(
                        "INSERT INTO users (id, name) VALUES ($1, $2)",
                        &[&id, &"John Doe"],
                    )
                    .await?;
                println!("Record added.");
            }
            "d" => {
                // レコードの削除
                client.execute("DELETE FROM users", &[]).await?;
                println!("All records deleted.");
            }
            "s" => {
                // レコードのソートと表示
                let rows = client
                    .query("SELECT id, name FROM users ORDER BY id", &[])
                    .await?;
                for row in rows {
                    let id: i32 = row.get(0);
                    let name: &str = row.get(1);
                    println!("ID: {}, Name: {}", id, name);
                }
            }
            _ => {
                break;
            }
        }
    }

    Ok(())
}

3. 在Rust中输入[a, s, d]等来操作记录

cargo run

用中文将以下内容进行释义: “で” (只需要一个选项)

在中文中释义为”通过”或”以…方式”的意思,表示一种方式或手段。

Press 'a' to add a record, 'd' to delete all records, 's' to sort and display records, or any other key to exit.

因为显示了类似于[a],[d],[s]之类的内容,所以我们可以通过点击来操控并进行录制。

Press 'a' to add a record, 'd' to delete all records, 's' to sort and display records, or any other key to exit.
a
Record added.
a
Record added.
a
Record added.
s
ID: -2115227795, Name: John Doe
ID: -1966422589, Name: John Doe
ID: -838073477, Name: John Doe

我成功地创建了一个正确的表格。
它以ID为依据进行了谨慎的排序。

4. 在PostgreSQL中查看表

sudo -u postgres 
psql -d type_record -c "SELECT * FROM users;"

执行。
如果能得到以下类似的结果就算成功了。

postgres=# \c type_record
You are now connected to database "type_record" as user "postgres".
type_record=#  SELECT * FROM users;
     id      |   name   
-------------+----------
  -838073477 | John Doe
 -1966422589 | John Doe
 -2115227795 | John Doe
(3 rows)

結論として

我成功地通过Rust能够操作本地的PostgreSQL。
如果还能和Heroku或Render.com上的PostgreSQL进行协作,将会扩展Web应用开发的范围。
辛苦了。

广告
将在 10 秒后关闭
bannerAds