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 {}
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 | integer | 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>,
}
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.