pub trait EntityTrait: EntityName {
    type Model: ModelTrait<Entity = Self> + FromQueryResult;
    type Column: ColumnTrait;
    type Relation: RelationTrait;
    type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>;

    fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>
    where
        R: EntityTrait
, { ... } fn has_one<R>(_: R) -> RelationBuilder<Self, R>
    where
        R: EntityTrait + Related<Self>
, { ... } fn has_many<R>(_: R) -> RelationBuilder<Self, R>
    where
        R: EntityTrait + Related<Self>
, { ... } fn find() -> Select<Self> { ... } fn find_by_id(
        values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType
    ) -> Select<Self> { ... } fn insert<A>(model: A) -> Insert<A>
    where
        A: ActiveModelTrait<Entity = Self>
, { ... } fn insert_many<A, I>(models: I) -> Insert<A>
    where
        A: ActiveModelTrait<Entity = Self>,
        I: IntoIterator<Item = A>
, { ... } fn update<A>(model: A) -> UpdateOne<A>
    where
        A: ActiveModelTrait<Entity = Self>
, { ... } fn update_many() -> UpdateMany<Self> { ... } fn delete<A>(model: A) -> DeleteOne<A>
    where
        A: ActiveModelTrait<Entity = Self>
, { ... } fn delete_many() -> DeleteMany<Self> { ... } fn delete_by_id(
        values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType
    ) -> DeleteMany<Self> { ... } }
Expand description

An Entity implementing EntityTrait represents a table in a database.

This trait provides an API for you to inspect it’s properties

This trait also provides an API for CRUD actions

  • Select: find, find_*
  • Insert: insert, insert_*
  • Update: update, update_*
  • Delete: delete, delete_*

Required Associated Types§

Provided Methods§

Check if the relation belongs to an Entity

Check if the entity has at least one relation

Check if the Entity has many relations

Construct select statement to find one / all models

  • To select columns, join tables and group by expressions, see QuerySelect
  • To apply where conditions / filters, see QueryFilter
  • To apply order by expressions, see QueryOrder
Example
use sea_orm::{entity::*, query::*, tests_cfg::cake};

assert_eq!(
    cake::Entity::find().one(&db).await?,
    Some(cake::Model {
        id: 1,
        name: "New York Cheese".to_owned(),
    })
);

assert_eq!(
    cake::Entity::find().all(&db).await?,
    vec![
        cake::Model {
            id: 1,
            name: "New York Cheese".to_owned(),
        },
        cake::Model {
            id: 2,
            name: "Chocolate Forest".to_owned(),
        },
    ]
);

assert_eq!(
    db.into_transaction_log(),
    vec![
        Transaction::from_sql_and_values(
            DbBackend::Postgres,
            r#"SELECT "cake"."id", "cake"."name" FROM "cake" LIMIT $1"#,
            vec![1u64.into()]
        ),
        Transaction::from_sql_and_values(
            DbBackend::Postgres,
            r#"SELECT "cake"."id", "cake"."name" FROM "cake""#,
            vec![]
        ),
    ]
);
Examples found in repository?
src/entity/base_entity.rs (line 260)
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    fn find_by_id(values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType) -> Select<Self> {
        let mut select = Self::find();
        let mut keys = Self::PrimaryKey::iter();
        for v in values.into_value_tuple() {
            if let Some(key) = keys.next() {
                let col = key.into_column();
                select = select.filter(col.eq(v));
            } else {
                panic!("primary key arity mismatch");
            }
        }
        if keys.next().is_some() {
            panic!("primary key arity mismatch");
        }
        select
    }

Find a model by primary key

Example
use sea_orm::{entity::*, query::*, tests_cfg::cake};

assert_eq!(
    cake::Entity::find_by_id(11).all(&db).await?,
    vec![cake::Model {
        id: 11,
        name: "Sponge Cake".to_owned(),
    }]
);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"SELECT "cake"."id", "cake"."name" FROM "cake" WHERE "cake"."id" = $1"#,
        vec![11i32.into()]
    )]
);

Find by composite key

use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};

assert_eq!(
    cake_filling::Entity::find_by_id((2, 3)).all(&db).await?,
    vec![cake_filling::Model {
        cake_id: 2,
        filling_id: 3,
    }]
);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        [
            r#"SELECT "cake_filling"."cake_id", "cake_filling"."filling_id" FROM "cake_filling""#,
            r#"WHERE "cake_filling"."cake_id" = $1 AND "cake_filling"."filling_id" = $2"#,
        ].join(" ").as_str(),
        vec![2i32.into(), 3i32.into()]
    )]);
Examples found in repository?
src/executor/insert.rs (line 202)
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
async fn exec_insert_with_returning<A, C>(
    primary_key: Option<ValueTuple>,
    mut insert_statement: InsertStatement,
    db: &C,
) -> Result<<A::Entity as EntityTrait>::Model, DbErr>
where
    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,
    C: ConnectionTrait,
    A: ActiveModelTrait,
{
    let db_backend = db.get_database_backend();
    let found = match db.support_returning() {
        true => {
            let returning = Query::returning().exprs(
                <A::Entity as EntityTrait>::Column::iter()
                    .map(|c| cast_enum_as_text(Expr::col(c), &c)),
            );
            insert_statement.returning(returning);
            SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
                db_backend.build(&insert_statement),
            )
            .one(db)
            .await?
        }
        false => {
            let insert_res =
                exec_insert::<A, _>(primary_key, db_backend.build(&insert_statement), db).await?;
            <A::Entity as EntityTrait>::find_by_id(insert_res.last_insert_id)
                .one(db)
                .await?
        }
    };
    match found {
        Some(model) => Ok(model),
        None => Err(DbErr::RecordNotFound(
            "Failed to find inserted item".to_owned(),
        )),
    }
}
More examples
Hide additional examples
src/executor/update.rs (line 121)
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
async fn exec_update_and_return_updated<A, C>(
    mut query: UpdateStatement,
    model: A,
    db: &C,
) -> Result<<A::Entity as EntityTrait>::Model, DbErr>
where
    A: ActiveModelTrait,
    C: ConnectionTrait,
{
    match db.support_returning() {
        true => {
            let returning = Query::returning().exprs(
                <A::Entity as EntityTrait>::Column::iter()
                    .map(|c| cast_enum_as_text(Expr::col(c), &c)),
            );
            query.returning(returning);
            let db_backend = db.get_database_backend();
            let found: Option<<A::Entity as EntityTrait>::Model> =
                SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
                    db_backend.build(&query),
                )
                .one(db)
                .await?;
            // If we got `None` then we are updating a row that does not exist.
            match found {
                Some(model) => Ok(model),
                None => Err(DbErr::RecordNotFound(
                    "None of the database rows are affected".to_owned(),
                )),
            }
        }
        false => {
            // If we updating a row that does not exist then an error will be thrown here.
            Updater::new(query).check_record_exists().exec(db).await?;
            let primary_key_value = match model.get_primary_key_value() {
                Some(val) => FromValueTuple::from_value_tuple(val),
                None => return Err(DbErr::UpdateGetPrimaryKey),
            };
            let found = <A::Entity as EntityTrait>::find_by_id(primary_key_value)
                .one(db)
                .await?;
            // If we cannot select the updated row from db by the cached primary key
            match found {
                Some(model) => Ok(model),
                None => Err(DbErr::RecordNotFound(
                    "Failed to find updated item".to_owned(),
                )),
            }
        }
    }
}

Insert an model into database

Example (Postgres)
use sea_orm::{entity::*, query::*, tests_cfg::cake};

let apple = cake::ActiveModel {
    name: Set("Apple Pie".to_owned()),
    ..Default::default()
};

let insert_result = cake::Entity::insert(apple).exec(&db).await?;

assert_eq!(dbg!(insert_result.last_insert_id), 15);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id""#,
        vec!["Apple Pie".into()]
    )]
);
Example (MySQL)
use sea_orm::{entity::*, query::*, tests_cfg::cake};

let apple = cake::ActiveModel {
    name: Set("Apple Pie".to_owned()),
    ..Default::default()
};

let insert_result = cake::Entity::insert(apple).exec(&db).await?;

assert_eq!(insert_result.last_insert_id, 15);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::MySql,
        r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
        vec!["Apple Pie".into()]
    )]
);
Examples found in repository?
src/entity/active_model.rs (line 282)
275
276
277
278
279
280
281
282
283
284
285
286
    async fn insert<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
    where
        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
        Self: ActiveModelBehavior + 'a,
        C: ConnectionTrait,
    {
        let am = ActiveModelBehavior::before_save(self, true)?;
        let model = <Self::Entity as EntityTrait>::insert(am)
            .exec_with_returning(db)
            .await?;
        Self::after_save(model, true)
    }

Insert many models into database

Example (Postgres)
use sea_orm::{entity::*, query::*, tests_cfg::cake};

let apple = cake::ActiveModel {
    name: Set("Apple Pie".to_owned()),
    ..Default::default()
};
let orange = cake::ActiveModel {
    name: Set("Orange Scone".to_owned()),
    ..Default::default()
};

let insert_result = cake::Entity::insert_many(vec![apple, orange])
    .exec(&db)
    .await?;

assert_eq!(insert_result.last_insert_id, 28);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"INSERT INTO "cake" ("name") VALUES ($1), ($2) RETURNING "id""#,
        vec!["Apple Pie".into(), "Orange Scone".into()]
    )]
);
Example (MySQL)
use sea_orm::{entity::*, query::*, tests_cfg::cake};

let apple = cake::ActiveModel {
    name: Set("Apple Pie".to_owned()),
    ..Default::default()
};
let orange = cake::ActiveModel {
    name: Set("Orange Scone".to_owned()),
    ..Default::default()
};

let insert_result = cake::Entity::insert_many(vec![apple, orange])
    .exec(&db)
    .await?;

assert_eq!(insert_result.last_insert_id, 28);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::MySql,
        r#"INSERT INTO `cake` (`name`) VALUES (?), (?)"#,
        vec!["Apple Pie".into(), "Orange Scone".into()]
    )]
);

Update an model in database

Example (Postgres)
use sea_orm::{entity::*, query::*, tests_cfg::fruit};

let orange = fruit::ActiveModel {
    id: Set(1),
    name: Set("Orange".to_owned()),
    ..Default::default()
};

assert_eq!(
    fruit::Entity::update(orange.clone())
        .filter(fruit::Column::Name.contains("orange"))
        .exec(&db)
        .await?,
    fruit::Model {
        id: 1,
        name: "Orange".to_owned(),
        cake_id: None,
    }
);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 AND "fruit"."name" LIKE $3 RETURNING "id", "name", "cake_id""#,
        vec!["Orange".into(), 1i32.into(), "%orange%".into()]
    )]);
Example (MySQL)
use sea_orm::{entity::*, query::*, tests_cfg::fruit};

let orange = fruit::ActiveModel {
    id: Set(1),
    name: Set("Orange".to_owned()),
    ..Default::default()
};

assert_eq!(
    fruit::Entity::update(orange.clone())
        .filter(fruit::Column::Name.contains("orange"))
        .exec(&db)
        .await?,
    fruit::Model {
        id: 1,
        name: "Orange".to_owned(),
        cake_id: None,
    }
);

assert_eq!(
    db.into_transaction_log(),
    vec![
        Transaction::from_sql_and_values(
            DbBackend::MySql,
            r#"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ? AND `fruit`.`name` LIKE ?"#,
            vec!["Orange".into(), 1i32.into(), "%orange%".into()]
        ),
        Transaction::from_sql_and_values(
            DbBackend::MySql,
            r#"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?"#,
            vec![1i32.into(), 1u64.into()]
        )]);
Examples found in repository?
src/entity/active_model.rs (line 404)
397
398
399
400
401
402
403
404
405
406
    async fn update<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
    where
        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
        Self: ActiveModelBehavior + 'a,
        C: ConnectionTrait,
    {
        let am = ActiveModelBehavior::before_save(self, false)?;
        let model: <Self::Entity as EntityTrait>::Model = Self::Entity::update(am).exec(db).await?;
        Self::after_save(model, false)
    }

Update many models in database

Example
use sea_orm::{
    entity::*,
    query::*,
    sea_query::{Expr, Value},
    tests_cfg::fruit,
};

let update_result = fruit::Entity::update_many()
    .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))
    .filter(fruit::Column::Name.contains("Apple"))
    .exec(&db)
    .await?;

assert_eq!(update_result.rows_affected, 5);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"UPDATE "fruit" SET "cake_id" = $1 WHERE "fruit"."name" LIKE $2"#,
        vec![Value::Int(None), "%Apple%".into()]
    )]
);

Delete an model from database

Example
use sea_orm::{entity::*, query::*, tests_cfg::fruit};

let orange = fruit::ActiveModel {
    id: Set(3),
    ..Default::default()
};

let delete_result = fruit::Entity::delete(orange).exec(&db).await?;

assert_eq!(delete_result.rows_affected, 1);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
        vec![3i32.into()]
    )]
);
Examples found in repository?
src/entity/active_model.rs (line 482)
475
476
477
478
479
480
481
482
483
484
485
    async fn delete<'a, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>
    where
        Self: ActiveModelBehavior + 'a,
        C: ConnectionTrait,
    {
        let am = ActiveModelBehavior::before_delete(self)?;
        let am_clone = am.clone();
        let delete_res = Self::Entity::delete(am).exec(db).await?;
        ActiveModelBehavior::after_delete(am_clone)?;
        Ok(delete_res)
    }

Delete many models from database

Example
use sea_orm::{entity::*, query::*, tests_cfg::fruit};

let delete_result = fruit::Entity::delete_many()
    .filter(fruit::Column::Name.contains("Apple"))
    .exec(&db)
    .await?;

assert_eq!(delete_result.rows_affected, 5);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "fruit" WHERE "fruit"."name" LIKE $1"#,
        vec!["%Apple%".into()]
    )]
);
Examples found in repository?
src/entity/base_entity.rs (line 823)
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
    fn delete_by_id(values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType) -> DeleteMany<Self> {
        let mut delete = Self::delete_many();
        let mut keys = Self::PrimaryKey::iter();
        for v in values.into_value_tuple() {
            if let Some(key) = keys.next() {
                let col = key.into_column();
                delete = delete.filter(col.eq(v));
            } else {
                panic!("primary key arity mismatch");
            }
        }
        if keys.next().is_some() {
            panic!("primary key arity mismatch");
        }
        delete
    }

Delete a model based on primary key

Example
use sea_orm::{entity::*, query::*, tests_cfg::fruit};

let delete_result = fruit::Entity::delete_by_id(1).exec(&db).await?;

assert_eq!(delete_result.rows_affected, 1);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
        vec![1i32.into()]
    )]
);

Delete by composite key


use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};

let delete_result = cake_filling::Entity::delete_by_id((2, 3)).exec(&db).await?;

assert_eq!(delete_result.rows_affected, 1);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "cake_filling" WHERE "cake_filling"."cake_id" = $1 AND "cake_filling"."filling_id" = $2"#,
        vec![2i32.into(), 3i32.into()]
    )]
);

Implementors§