Trait sea_orm::entity::EntityTrait
source · 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
- Column (implemented
ColumnTrait
) - Relation (implemented
RelationTrait
) - Primary Key (implemented
PrimaryKeyTrait
andPrimaryKeyToColumn
)
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 Column: ColumnTrait
type Relation: RelationTrait
type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>
Provided Methods§
sourcefn belongs_to<R>(related: R) -> RelationBuilder<Self, R>where
R: EntityTrait,
fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>where
R: EntityTrait,
Check if the relation belongs to an Entity
sourcefn has_one<R>(_: R) -> RelationBuilder<Self, R>where
R: EntityTrait + Related<Self>,
fn has_one<R>(_: R) -> RelationBuilder<Self, R>where
R: EntityTrait + Related<Self>,
Check if the entity has at least one relation
sourcefn has_many<R>(_: R) -> RelationBuilder<Self, R>where
R: EntityTrait + Related<Self>,
fn has_many<R>(_: R) -> RelationBuilder<Self, R>where
R: EntityTrait + Related<Self>,
Check if the Entity has many relations
sourcefn find() -> Select<Self>
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?,
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
}
sourcefn find_by_id(
values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType
) -> Select<Self>
fn find_by_id(
values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType
) -> Select<Self>
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
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(),
)),
}
}
}
}
sourcefn insert<A>(model: A) -> Insert<A>where
A: ActiveModelTrait<Entity = Self>,
fn insert<A>(model: A) -> Insert<A>where
A: ActiveModelTrait<Entity = Self>,
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)
}
sourcefn insert_many<A, I>(models: I) -> Insert<A>where
A: ActiveModelTrait<Entity = Self>,
I: IntoIterator<Item = A>,
fn insert_many<A, I>(models: I) -> Insert<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(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()]
)]
);
sourcefn update<A>(model: A) -> UpdateOne<A>where
A: ActiveModelTrait<Entity = Self>,
fn update<A>(model: A) -> UpdateOne<A>where
A: ActiveModelTrait<Entity = Self>,
Update an model in database
- To apply where conditions / filters, see
QueryFilter
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()]
)]);
sourcefn update_many() -> UpdateMany<Self>
fn update_many() -> UpdateMany<Self>
Update many models in database
- To apply where conditions / filters, see
QueryFilter
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()]
)]
);
sourcefn delete<A>(model: A) -> DeleteOne<A>where
A: ActiveModelTrait<Entity = Self>,
fn delete<A>(model: A) -> DeleteOne<A>where
A: ActiveModelTrait<Entity = Self>,
Delete an model from database
- To apply where conditions / filters, see
QueryFilter
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()]
)]
);
sourcefn delete_many() -> DeleteMany<Self>
fn delete_many() -> DeleteMany<Self>
Delete many models from database
- To apply where conditions / filters, see
QueryFilter
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
}
sourcefn delete_by_id(
values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType
) -> DeleteMany<Self>
fn delete_by_id(
values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType
) -> DeleteMany<Self>
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()]
)]
);