

🐚 SeaORM is a relational ORM to help you build web services in Rust
Async
Relying on SQLx, SeaORM is a new library with async support from day 1.
Dynamic
Built upon SeaQuery, SeaORM allows you to build complex dynamic queries.
Testable
Use mock connections and/or SQLite to write tests for your application logic.
Service Oriented
Quickly build services that join, filter, sort and paginate data in REST, GraphQL and gRPC APIs.
A quick taste of SeaORM
- Entity
- Select
- Insert
- Update
- Save
- Delete
use sea_orm::entity::prelude::*;#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]#[sea_orm(table_name = "cake")]pub struct Model {#[sea_orm(primary_key)]pub id: i32,pub name: String,}#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]pub enum Relation {#[sea_orm(has_many = "super::fruit::Entity")]Fruit,}impl Related<super::fruit::Entity> for Entity {fn to() -> RelationDef {Relation::Fruit.def()}}
// find all modelslet cakes: Vec<cake::Model> = Cake::find().all(db).await?;// find and filterlet chocolate: Vec<cake::Model> = Cake::find().filter(cake::Column::Name.contains("chocolate")).all(db).await?;// find one modellet cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;let cheese: cake::Model = cheese.unwrap();// find related models (lazy)let fruits: Vec<fruit::Model> = cheese.find_related(Fruit).all(db).await?;// find related models (eager)let cake_with_fruits: Vec<(cake::Model, Vec<fruit::Model>)> =Cake::find().find_with_related(Fruit).all(db).await?;
let apple = fruit::ActiveModel {name: Set("Apple".to_owned()),..Default::default() // no need to set primary key};let pear = fruit::ActiveModel {name: Set("Pear".to_owned()),..Default::default()};// insert onelet pear = pear.insert(db).await?;// insert manyFruit::insert_many([apple, pear]).exec(db).await?;
use sea_orm::sea_query::{Expr, Value};let pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;let mut pear: fruit::ActiveModel = pear.unwrap().into();pear.name = Set("Sweet pear".to_owned());// update onelet pear: fruit::Model = pear.update(db).await?;// update many: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%'Fruit::update_many().col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None))).filter(fruit::Column::Name.contains("Apple")).exec(db).await?;
let banana = fruit::ActiveModel {id: NotSet,name: Set("Banana".to_owned()),..Default::default()};// create, because primary key `id` is `NotSet`let mut banana = banana.save(db).await?;banana.name = Set("Banana Mongo".to_owned());// update, because primary key `id` is `Set`let banana = banana.save(db).await?;
// delete onelet orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;let orange: fruit::Model = orange.unwrap();fruit::Entity::delete(orange.into_active_model()).exec(db).await?;// or simplylet orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;let orange: fruit::Model = orange.unwrap();orange.delete(db).await?;// delete many: DELETE FROM "fruit" WHERE "fruit"."name" LIKE 'Orange'fruit::Entity::delete_many().filter(fruit::Column::Name.contains("Orange")).exec(db).await?;
SeaORM ➕ GraphQL = 🧭 Seaography
With Seaography, you can easily launch a GraphQL server from SeaORM entities!

Who's using SeaORM?
The following startups are using SeaORM:
For more projects, see Built with SeaORM.
Meet Terres, our official mascot
A friend of Ferris, Terres the hermit crab is a member of the Rustacean family.
