EntityTrait

Trait EntityTrait 

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

Show 15 methods // Provided methods 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 has_many_via<R, T>(_: R, rel: T) -> RelationBuilder<Self, R> where R: EntityTrait, T: RelationTrait { ... } fn find() -> Select<Self> { ... } fn find_by_id<T>(values: T) -> Select<Self> where T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType> { ... } fn primary_key_identity() -> Identity { ... } fn column_tuple_in<I>( columns: I, values: &[ValueTuple], db_backend: DbBackend, ) -> Result<Condition, DbErr> where I: IntoIterator<Item = Self::Column> { ... } fn insert<A>(model: A) -> Insert<A> where A: ActiveModelTrait<Entity = Self> { ... } fn insert_many<A, I>(models: I) -> InsertMany<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<Self> where A: ActiveModelTrait<Entity = Self> { ... } fn delete_many() -> DeleteMany<Self> { ... } fn delete_by_id<T>(values: T) -> ValidatedDeleteOne<Self> where T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType> { ... }
}
Expand description

An abstract base class for defining Entities.

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§

type Model: ModelTrait<Entity = Self> + FromQueryResult

type ModelEx: ModelTrait<Entity = Self>

type ActiveModel: ActiveModelBehavior<Entity = Self>

type ActiveModelEx: ActiveModelTrait<Entity = Self>

type Column: ColumnTrait

type Relation: RelationTrait

type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>

Provided Methods§

fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>
where R: EntityTrait,

Construct a belongs to relation, where this table has a foreign key to another table.

fn has_one<R>(_: R) -> RelationBuilder<Self, R>
where R: EntityTrait + Related<Self>,

Construct a has one relation

fn has_many<R>(_: R) -> RelationBuilder<Self, R>
where R: EntityTrait + Related<Self>,

Construct a has many relation

fn has_many_via<R, T>(_: R, rel: T) -> RelationBuilder<Self, R>

Construct a has many relation, with the Relation provided. This is for the case where Related<Self> is not possible.

fn find() -> Select<Self>

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?,
    [
        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(),
    [
        Transaction::from_sql_and_values(
            DbBackend::Postgres,
            r#"SELECT "cake"."id", "cake"."name" FROM "cake" LIMIT $1"#,
            [1u64.into()]
        ),
        Transaction::from_sql_and_values(
            DbBackend::Postgres,
            r#"SELECT "cake"."id", "cake"."name" FROM "cake""#,
            []
        ),
    ]
);

fn find_by_id<T>(values: T) -> Select<Self>
where T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType>,

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?,
    [cake::Model {
        id: 11,
        name: "Sponge Cake".to_owned(),
    }]
);

assert_eq!(
    db.into_transaction_log(),
    [Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"SELECT "cake"."id", "cake"."name" FROM "cake" WHERE "cake"."id" = $1"#,
        [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?,
    [cake_filling::Model {
        cake_id: 2,
        filling_id: 3,
    }]
);

assert_eq!(
    db.into_transaction_log(),
    [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(),
        [2i32.into(), 3i32.into()]
    )]);

fn primary_key_identity() -> Identity

Get primary key as Identity

fn column_tuple_in<I>( columns: I, values: &[ValueTuple], db_backend: DbBackend, ) -> Result<Condition, DbErr>
where I: IntoIterator<Item = Self::Column>,

Construct a WHERE (c1, c2, ...) IN ((v11, v12, ...), ...) condition for arbitrary columns and value tuples.

For databases that don’t support tuple value syntax (MSSQL, and SQLite before 3.15 when the sqlite-no-row-value-before-3_15 feature is enabled), this automatically falls back to an equivalent (c1 = v11 AND c2 = v12) OR (c1 = v21 AND c2 = v22) ... expression.

§Example
use sea_orm::{entity::*, query::*, tests_cfg::cake, DbBackend};
use sea_query::IntoValueTuple;

assert_eq!(
    cake::Entity::find()
        .filter(cake::Entity::column_tuple_in(
            [cake::Column::Id, cake::Column::Name],
            &[(1i32, "a").into_value_tuple(), (2i32, "b").into_value_tuple()],
            DbBackend::MySql,
        ).unwrap())
        .build(DbBackend::MySql)
        .to_string(),
    "SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE (`cake`.`id`, `cake`.`name`) IN ((1, 'a'), (2, 'b'))"
);
assert_eq!(
    cake::Entity::find()
        .filter(cake::Entity::column_tuple_in(
            [cake::Column::Id, cake::Column::Name],
            &[(1i32, "a").into_value_tuple(), (2i32, "b").into_value_tuple()],
            DbBackend::MsSql,
        ).unwrap())
        .build(DbBackend::MsSql)
        .to_string(),
    "SELECT [cake].[id], [cake].[name] FROM [cake] WHERE ([cake].[id] = 1 AND [cake].[name] = 'a') OR ([cake].[id] = 2 AND [cake].[name] = 'b')"
);

Return DbErr::Type if columns is empty.

fn insert<A>(model: A) -> Insert<A>
where A: ActiveModelTrait<Entity = Self>,

Insert a 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(),
    [Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id""#,
        ["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(),
    [Transaction::from_sql_and_values(
        DbBackend::MySql,
        r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
        ["Apple Pie".into()]
    )]
);

To get back inserted Model

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

assert_eq!(
    cake::Entity::insert(cake::ActiveModel {
        id: NotSet,
        name: Set("Apple Pie".to_owned()),
    })
    .exec_with_returning(&db)
    .await?,
    cake::Model {
        id: 1,
        name: "Apple Pie".to_owned(),
    }
);

assert_eq!(
    db.into_transaction_log()[0].statements()[0].sql,
    r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id", "name""#
);

fn insert_many<A, I>(models: I) -> InsertMany<A>
where A: ActiveModelTrait<Entity = Self>, I: IntoIterator<Item = A>,

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::<cake::ActiveModel, _>([])
    .exec(&db)
    .await?;

assert_eq!(insert_result.last_insert_id, None);

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

assert_eq!(insert_result.last_insert_id, Some(28));

assert_eq!(
    db.into_transaction_log(),
    [Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"INSERT INTO "cake" ("name") VALUES ($1), ($2) RETURNING "id""#,
        ["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([apple, orange]).exec(&db).await?;

assert_eq!(insert_result.last_insert_id, Some(28));

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

Before 1.1.3, if the active models have different column set, this method would panic. Now, it’d attempt to fill in the missing columns with null (which may or may not be correct, depending on whether the column is nullable):

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

assert_eq!(
    cake::Entity::insert_many([
        cake::ActiveModel {
            id: NotSet,
            name: Set("Apple Pie".to_owned()),
        },
        cake::ActiveModel {
            id: NotSet,
            name: Set("Orange Scone".to_owned()),
        }
    ])
    .build(DbBackend::Postgres)
    .to_string(),
    r#"INSERT INTO "cake" ("name") VALUES ('Apple Pie'), ('Orange Scone')"#,
);

assert_eq!(
    cake_filling::Entity::insert_many([
        cake_filling::ActiveModel {
            cake_id: ActiveValue::set(2),
            filling_id: ActiveValue::NotSet,
        },
        cake_filling::ActiveModel {
            cake_id: ActiveValue::NotSet,
            filling_id: ActiveValue::set(3),
        }
    ])
    .build(DbBackend::Postgres)
    .to_string(),
    r#"INSERT INTO "cake_filling" ("cake_id", "filling_id") VALUES (2, NULL), (NULL, 3)"#,
);

To get back inserted Models

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

assert_eq!(
    cake::Entity::insert_many([
        cake::ActiveModel {
            id: NotSet,
            name: Set("Apple Pie".to_owned()),
        },
        cake::ActiveModel {
            id: NotSet,
            name: Set("Choco Pie".to_owned()),
        },
    ])
    .exec_with_returning(&db)
    .await?,
    [
        cake::Model {
            id: 1,
            name: "Apple Pie".to_owned(),
        },
        cake::Model {
            id: 2,
            name: "Choco Pie".to_owned(),
        }
    ]
);

assert_eq!(
    db.into_transaction_log()[0].statements()[0].sql,
    r#"INSERT INTO "cake" ("name") VALUES ($1), ($2) RETURNING "id", "name""#
);

fn update<A>(model: A) -> UpdateOne<A>
where A: ActiveModelTrait<Entity = Self>,

Update a 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())
        .validate()?
        .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(),
    [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""#,
        ["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())
        .validate()?
        .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(),
    [
        Transaction::from_sql_and_values(
            DbBackend::MySql,
            r#"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ? AND `fruit`.`name` LIKE ?"#,
            ["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 ?"#,
            [1i32.into(), 1u64.into()]
        )]);

fn update_many() -> UpdateMany<Self>

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(),
    [Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"UPDATE "fruit" SET "cake_id" = $1 WHERE "fruit"."name" LIKE $2"#,
        [Value::Int(None), "%Apple%".into()]
    )]
);

fn delete<A>(model: A) -> DeleteOne<Self>
where A: ActiveModelTrait<Entity = Self>,

Delete a 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(),
    [Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
        [3i32.into()]
    )]
);

fn delete_many() -> DeleteMany<Self>

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(),
    [Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "fruit" WHERE "fruit"."name" LIKE $1"#,
        ["%Apple%".into()]
    )]
);

fn delete_by_id<T>(values: T) -> ValidatedDeleteOne<Self>
where T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType>,

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(),
    [Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
        [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(),
    [Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "cake_filling" WHERE "cake_filling"."cake_id" = $1 AND "cake_filling"."filling_id" = $2"#,
        [2i32.into(), 3i32.into()]
    )]
);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§