Insert
Before diving into SeaORM insert we have to introduce ActiveValue
and ActiveModel
.
ActiveValue
A wrapper struct to capture the changes made to ActiveModel
attributes.
use sea_orm::ActiveValue::NotSet;
// Set value
let _: ActiveValue<i32> = Set(10);
// NotSet value
let _: ActiveValue<i32> = NotSet;
Model & ActiveModel
An ActiveModel
has all the attributes of Model
wrapped in ActiveValue
.
You can use ActiveModel
to insert a row with a subset of columns set.
let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;
// Get Model
let model: cake::Model = cheese.unwrap();
assert_eq!(model.name, "Cheese Cake".to_owned());
// Into ActiveModel
let active_model: cake::ActiveModel = model.into();
assert_eq!(active_model.name, ActiveValue::unchanged("Cheese Cake".to_owned()));
Set ActiveModel from JSON Value
If you want to save user input into the database you can easily convert JSON value into ActiveModel
. Note that you might want to skip deserializing JSON's primary key attribute, you can config that as shown below.
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "fruit")]
pub struct Model {
#[sea_orm(primary_key)]
#[serde(skip_deserializing)] // Skip deserializing
pub id: i32,
pub name: String,
pub cake_id: Option<i32>,
}
Set the attributes in ActiveModel
with set_from_json
method.
// A ActiveModel with primary key set
let mut fruit = fruit::ActiveModel {
id: ActiveValue::Set(1),
name: ActiveValue::NotSet,
cake_id: ActiveValue::NotSet,
};
// Note that this method will not alter the primary key values in ActiveModel
fruit.set_from_json(json!({
"id": 8,
"name": "Apple",
"cake_id": 1,
}))?;
assert_eq!(
fruit,
fruit::ActiveModel {
id: ActiveValue::Set(1),
name: ActiveValue::Set("Apple".to_owned()),
cake_id: ActiveValue::Set(Some(1)),
}
);
Create a new ActiveModel
from JSON value with the from_json
method.
let fruit = fruit::ActiveModel::from_json(json!({
"name": "Apple",
}))?;
assert_eq!(
fruit,
fruit::ActiveModel {
id: ActiveValue::NotSet,
name: ActiveValue::Set("Apple".to_owned()),
cake_id: ActiveValue::NotSet,
}
);
Insert One
Insert an active model and get back a fresh Model
. Its value is retrieved from database, so any auto-generated fields will be populated.
let pear = fruit::ActiveModel {
name: Set("Pear".to_owned()),
..Default::default() // all other attributes are `NotSet`
};
let pear: fruit::Model = pear.insert(db).await?;
Insert an active model and get back the last insert id. Its type matches the model's primary key type, so it could be a tuple if the model has a composite primary key.
let pear = fruit::ActiveModel {
name: Set("Pear".to_owned()),
..Default::default() // all other attributes are `NotSet`
};
let res: InsertResult = fruit::Entity::insert(pear).exec(db).await?;
assert_eq!(res.last_insert_id, 28)
Insert Many
Insert many active models and get back the last insert id.
let apple = fruit::ActiveModel {
name: Set("Apple".to_owned()),
..Default::default()
};
let orange = fruit::ActiveModel {
name: Set("Orange".to_owned()),
..Default::default()
};
let res: InsertResult = Fruit::insert_many(vec![apple, orange]).exec(db).await?;
assert_eq!(res.last_insert_id, 30)