Sea-orm Quick Start Guide for Rust

SeaORM is a relational ORM that helps you
build web services in Rust using a familiar dynamic language.

The official documentation for SeaORM is on their official website .

This guide uses PostgreSQL . Before we begin, make sure you
have PostgreSQL installed for your system .

In this tutorial, we'll build simple examples of each CRUD operation.

I'm using Rust  v1.62 and sea-ormv0.9

Initialize a new project

cargo new seaorm_demo --lib
cd seaorm_demo

First, let's add SeaORM and tokio to our dependencies.

document:Cargo.toml

[dependencies]
tokio = { version = "1.20", features = ["macros", "rt-multi-thread"] }

[dependencies.sea-orm]
version = "0.9"
features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ]
default-features = false

Install sea-orm-cli and migrate

cargo install sea-orm-cli

We'll write a migration file to set up our database and table schema.

sea-orm-cli migrate init

Next will generate a file named migration的目录  Now our project structure should look like this.

.
├── Cargo.lock
├── Cargo.toml
├── migration
│   ├── Cargo.toml
│   ├── README.md
│   └── src
│       ├── lib.rs
│       ├── m20220101_000001_create_table.rs
│       └── main.rs
└── src
    └── lib.rs

Open the file migration/Cargo.tomland uncomment the last two lines sea-orm-migration.

document:migration/Cargo.toml

[dependencies.sea-orm-migration]
version = "^0.9.0"
features = [
  # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.
  # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.
  # e.g.
   "runtime-tokio-rustls",  # `ASYNC_RUNTIME` featrure
   "sqlx-postgres",         # `DATABASE_DRIVER` feature
]

migration/src/m20220101_000001_create_table.rsEdit the file in your favorite editor
and delete the two
"todo!()" saves.

Create a new " .env " file in the project root directory

DATABASE_URL="postgres://root:root@localhost:5432/axum_example"

Next, we'll run the migration.

sea-orm-cli migrate up

It will compile migrationthe module and run your migrations. After this, you
should see a file called posts.pdb in your directory.

generate entity

Create a new entitymodule.

cargo new entity --lib

Next, generate entities.

sea-orm-cli generate entity -o entity/src

Add sea-ormdependencies to entitymodules.

document:entity/Cargo.toml

[dependencies]
sea-orm = { version = "0.9" }

The resulting entity should look like this.

document:entity/src/post.rs

//! SeaORM Entity. Generated by sea-orm-codegen 0.9.0

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "post")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub title: String,
    pub text: String,
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {}

impl RelationTrait for Relation {
    fn def(&self) -> RelationDef {
        panic!("No RelationDef")
    }
}

impl ActiveModelBehavior for ActiveModel {}

Since the module entityis in the root of our project, we remove lib.rs and turn mod.rs
into a library so we can use it.

Rename entity/src/mod.rsto entity/src/lib.rs.

mv entity/src/mod.rs entity/src/lib.rs

Next, we add entitythe and migrationlibrary to
the root project's dependencies.

document:Cargo.toml

[workspace]
members = [".", "entity", "migration"]

[dependencies]
entity = { path = "entity" }
migration = { path = "migration" }

Now your project structure should look like this

.
├── Cargo.lock
├── Cargo.toml
├── entity
│   ├── Cargo.toml
│   └── src
│       ├── lib.rs
│       ├── post.rs
│       └── prelude.rs
├── migration
│   ├── Cargo.lock
│   ├── Cargo.toml
│   ├── README.md
│   └── src
│       ├── lib.rs
│       ├── m20220101_000001_create_table.rs
│       └── main.rs
├── src
│   └── lib.rs
└── migration.pdb

项目Cargo.tomlIt should look like this.

document:Cargo.tmol

[package]
name = "seaorm_demo"
version = "0.1.0"
edition = "2021"

[workspace]
members = [".", "entity", "migration"]

[dependencies]
entity = { path = "entity" }
migration = { path = "migration" }
tokio = { version = "1.20", features = ["macros", "rt-multi-thread"] }

[dependencies.sea-orm]
version = "0.9"
features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ]
default-features = false

Connect to the database

Now we write the code to establish the connection to the database.

document:src/lib.rs

use migration::{DbErr, Migrator, MigratorTrait};
use sea_orm::{Database, DbConn};
const DATABASE_URL: &str = "postgres://root:root@localhost:5432/axum_example";

pub async fn establish_connection() -> Result<DbConn, DbErr> {
    let db = Database::connect(DATABASE_URL)
        .await
        .expect("连接数据库失败");
    Migrator::up(&db, None)
        .await
        .expect("迁移失败");

    Ok(db)
}

"Add" - add data

Now let's write some code to create a post. Create a new file src/bin/create_post.rs.

document:src/bin/create_post.rs

use migration::DbErr;
use sea_orm::{Set, ActiveModelTrait};
use seaorm_demo::establish_connection;
use entity::post;

#[tokio::main]
async fn main() -> Result<(), DbErr>{
    let db = establish_connection().await?;

    let post = post::ActiveModel {
        title: Set(String::from("我是title")),
        text: Set(String::from("我是text")),
        ..Default::default()
    };

    let post: post::Model = post.insert(&db).await?;

    println!("ID: {}, title: {}", post.id, post.title);

    Ok(())
}

We can run our new script as follows.

cargo run --bin create_post

It should look like this.

$ cargo run --bin create_post
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 3.85s
     Running `target/debug/create_post`
ID: 1, title: 我是title

If you wish to create more entries in the database, change the title/text
create_post.rsand execute the script again.

I will create another one.

$ cargo run --bin create_post
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 4.08s
     Running `target/debug/create_post`
ID: 2, title: 我是title

"check" - form query

Next, we write an example that reads all posts in the database.

document:src/bin/read_posts.rs

use migration::DbErr;
use sea_orm::EntityTrait;
use seaorm_demo::establish_connection;
use entity::post;

#[tokio::main]
async fn main() -> Result<(), DbErr>{
    let db = establish_connection().await?;

    let posts: Vec<post::Model> = post::Entity::find().all(&db).await?;

    println!("表中的所有帖子:");
    for post in posts {
        println!("id: {}, title: {}", post.id, post.title);
    }

    Ok(())
}

Just like before, you can run this new file as follows.

cargo run --bin read_posts

It should look like this.

$ cargo run --bin read_posts
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 4.08s
     Running `target/debug/read_posts`
表中的所有帖子:
ID: 1, title : 我是title
ID: 2, title : 我是title

"Change" - update data

Now, suppose we want to perform an UPDATE operation on the title of the post.

document:src/bin/update_post.rs

use migration::DbErr;
use sea_orm::{EntityTrait, Set, ActiveModelTrait};
use seaorm_demo::establish_connection;
use entity::post;

#[tokio::main]
async fn main() -> Result<(), DbErr>{
    let db = establish_connection().await?;

    //根据ID更新帖子内容
    let post = post::Entity::find_by_id(1).one(&db).await?;
    let mut post: post::ActiveModel = post.unwrap().into();
    post.title = Set("哈哈,我被更新啦".to_owned());
    let post: post::Model = post.update(&db).await?;

    println!("更新后的帖子id: {}  title: {}", post.id, post.title);

    Ok(())
}

we run this script

cargo run --bin update_post

It should look like this.

$ cargo run --bin update_post                                                                                         ⏎
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 2.80s
     Running `target/debug/update_post`
更新后的帖子id:1  title: 哈哈,我被更新啦

"delete" - delete data

Now for the final operation, delete. create a new filesrc/bin/delete_post.rs

We will delete post with id 1

document:src/bin/delete_post.rs

use migration::DbErr;
use sea_orm::{EntityTrait, DeleteResult, ModelTrait};
use seaorm_demo::establish_connection;
use entity::post;

#[tokio::main]
async fn main() -> Result<(), DbErr>{
    let db = establish_connection().await?;

    let post = post::Entity::find_by_id(1).one(&db).await?;
    let post: post::Model = post.unwrap();

    let res: DeleteResult = post.delete(&db).await?;
    assert_eq!(res.rows_affected, 1);

    println!("{:?}", res);

    Ok(())
}

We will call this script

cargo run --bin delete_post

It should look like this.

$ cargo run --bin delete_post
   Compiling seaorm_demo v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 5.42s
     Running `target/debug/delete_post`
DeleteResult { rows_affected: 1 }

We can execute the script again read_postto see what other posts are in the database.

$ cargo run --bin read_posts 
    Finished dev [unoptimized + debuginfo] target(s) in 0.31s
     Running `target/debug/read_posts`

ID: 2, title: 我是title

Guess you like

Origin blog.csdn.net/love906897406/article/details/126642259