Entity Structure
Let's look at a simple Cake entity.
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 ActiveModelBehavior for ActiveModel {}
Do not delete Relation enum or ActiveModelBehavior impl block even if you do not want any relations or additional behavior.
Keep their body empty is enough to make the entity just work.
Entity
The DeriveEntityModel macro does all the heavy lifting of defining an Entity with associating Model, Column and PrimaryKey.
Table Name
The table_name attribute specifies the corresponding table in the database.
Optionally, you can also specify the database schema or database name by schema_name.
#[sea_orm(table_name = "cake", schema_name = "public")]
pub struct Model { ... }
Column
Column Name
All column names are assumed to be in snake-case. You can override the column name by specifying the column_name attribute.
#[sea_orm(column_name = "name")]
pub name: String
Column Type
The column type will be derived automatically with the following mapping:
For the mappings of Rust primitive data types.
| Rust type | Database Type ( ColumnType) | SQLite datatype | MySQL datatype | PostgreSQL datatype |
|---|---|---|---|---|
String | Char | text | char | char |
String | String | text | varchar | varchar |
i8 | TinyInteger | integer | tinyint | char |
u8 | TinyUnsigned | integer | tinyint unsigned | N/A |
i16 | SmallInteger | integer | smallint | smallint |
u16 | SmallUnsigned | integer | smallint unsigned | N/A |
i32 | Integer | integer | int | integer |
u32 | Unsigned | integer | int unsigned | N/A |
i64 | BigInteger | integer | bigint | bigint |
u64 | BigUnsigned | N/A | bigint unsigned | N/A |
f32 | Float | real | float | real |
f64 | Double | real | double | double precision |
bool | Boolean | integer | bool | bool |
Vec<u8> | Binary | blob | blob | bytea |
For the mappings of Rust non-primitive data types. You can check entity/prelude.rs for all of the reexported types.
| Rust type | Database Type ( ColumnType) | SQLite datatype | MySQL datatype | PostgreSQL datatype |
|---|---|---|---|---|
Date: chrono::NaiveDate TimeDate: time::Date | Date | text | date | date |
Time: chrono::NaiveTime TimeTime: time::Time | Time | text | time | time |
DateTime: chrono::NaiveDateTime TimeDateTime: time::PrimitiveDateTime | DateTime | text | datetime | timestamp |
DateTimeLocal: chrono::DateTime<Local> DateTimeUtc: chrono::DateTime<Utc> | Timestamp | text | timestamp | N/A |
DateTimeWithTimeZone: chrono::DateTime<FixedOffset> TimeDateTimeWithTimeZone: time::OffsetDateTime | TimestampWithTimeZone | text | timestamp | timestamp with time zone |
Uuid: uuid::Uuid | Uuid | text | binary(16) | uuid |
Json: serde_json::Value | Json | text | json | json |
Decimal: rust_decimal::Decimal | Decimal | real | decimal | decimal |
You can override the default mappings between a Rust type and ColumnType by the column_type attribute.
#[sea_orm(column_type = "Text")]
pub name: String
If you need your JSON field to be deserialized into a struct. You would need to derive FromJsonQueryResult for it.
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "json_struct")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
// JSON column defined in `serde_json::Value`
pub json: Json,
// JSON column defined in custom struct
pub json_value: KeyValue,
pub json_value_opt: Option<KeyValue>,
}
// The custom struct must derive `FromJsonQueryResult`, `Serialize` and `Deserialize`
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, FromJsonQueryResult)]
pub struct KeyValue {
pub id: i32,
pub name: String,
pub price: f32,
pub notes: Option<String>,
}
Array datatype is supported for PostgreSQL, you can define a vector of any types that are already supported by SeaORM in the model. Keep in mind that you need to enable the postgres-array feature and this is a Postgres only feature.
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "collection")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub integers: Vec<i32>,
pub integers_opt: Option<Vec<i32>>,
pub floats: Vec<f32>,
pub doubles: Vec<f64>,
pub strings: Vec<String>,
}
Additional Properties
You can add additional properties default_value, unique, indexed and nullable to a column.
If you specified a custom column_type for an optional attribute, you must also specify nullable.
#[sea_orm(column_type = "Text", default_value = "Sam", unique, indexed, nullable)]
pub name: Option<String>
Ignore Attribute
If you want to ignore a particular model attribute such that it maps to no database column, you can use the ignore annotation.
#[sea_orm(ignore)]
pub ignore_me: String
Primary Key
Use the primary_key attribute to mark a column as the primary key.
#[sea_orm(primary_key)]
pub id: i32
Auto Increment
By default, auto_increment is implied for primary_key column. Override it by specifying false.
#[sea_orm(primary_key, auto_increment = false)]
pub id: i32
Composite Key
This is usually the case in junction tables, where a two-column tuple is used as the primary key. Simply annotate multiple columns to define a composite primary key. By default, auto_increment is false for composite key.
pub struct Model {
#[sea_orm(primary_key)]
pub cake_id: i32,
#[sea_orm(primary_key)]
pub fruit_id: i32,
}
Relation
The DeriveRelation macro is a simple wrapper to impl the RelationTrait.
#[derive(DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::fruit::Entity")]
Fruit,
}
expands into
impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
match self {
Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
}
}
}
Learn more about relations in the next section.