Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SeaORM

SeaORM maps database tables to Rust entities and active models, so you can create, query, and update rows with typed values instead of writing raw SQL for each step. The entity in the recipe below shows the generated Rust types clearly, but you do not need to write all of that code by hand when you already have a database schema. Use sea-orm-cli to generate entities from an existing database.

Create, query, and update rows with SeaORM

sea_orm-badge cat-database-badge

Use Database::connect to open an in-memory SQLite database and Schema::create_table_from_entity to create a table from a SeaORM entity. Create a row with ActiveModelTrait::save, load it with EntityTrait::find, then update it and check the saved value returned by ActiveModelTrait::save.

use sea_orm::sea_query::TableCreateStatement;
use sea_orm::{
    ActiveModelTrait, ConnectionTrait, Database, DatabaseBackend, DatabaseConnection, DbErr,
    EntityTrait, Schema, Set,
};

mod location {
    use sea_orm::entity::prelude::*;

    #[derive(Debug, Clone, PartialEq, DeriveEntityModel)]
    #[sea_orm(table_name = "location")]
    pub struct Model {
        #[sea_orm(primary_key)]
        pub id: i32,
        pub name: String,
        pub latitude: f64,
        pub longitude: f64,
    }

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

    impl ActiveModelBehavior for ActiveModel {}
}

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

    create_location_table(&db).await?;

    let mut null_island = location::ActiveModel {
        name: Set("Null Island".to_owned()),
        latitude: Set(0.0),
        longitude: Set(0.0),
        ..Default::default()
    }
    .save(&db)
    .await?;

    let location = location::Entity::find().one(&db).await?;
    println!("{location:?}");

    null_island.name = Set("Null Island V2".to_owned());
    let null_island = null_island.save(&db).await?;

    println!("Updated location: {null_island:?}");
    Ok(())
}

async fn create_location_table(db: &DatabaseConnection) -> Result<(), DbErr> {
    let builder = DatabaseBackend::Sqlite;
    let schema = Schema::new(builder);

    let statement: TableCreateStatement = schema.create_table_from_entity(location::Entity);
    db.execute(builder.build(&statement)).await?;
    Ok(())
}