Defining Entities & Models
Relevant source files
The following files were used as context for generating this wiki page:
SeaORM 2.0 introduces an expressive and developer-friendly format for defining database entities and models. The core of this system is the Model struct, which represents the data structure of a database row, and the Entity type, which provides the interface for database operations. The system supports various relationship types (1-1, 1-N, M-N, and self-referential) and offers high-level conceptual modeling inspired by popular ORMs in other ecosystems.
Entities in SeaORM act as the bridge between Rust's type system and relational database schemas. With the release of version 2.0, the framework emphasizes an "Entity First" workflow where developers define models in Rust, and SeaORM handles schema synchronization, including table creation and foreign key constraint management.
Sources: CLAUDE.md:14-23, src/lib.rs:17-38
Entity Definition Architecture
In SeaORM, an entity is primarily defined using the #[sea_orm::model] attribute on a Model struct. This macro generates the necessary boilerplate for implementing traits like EntityTrait, ModelTrait, and ActiveModelTrait.
Core Components of an Entity
| Component | Description |
|---|---|
| Model Struct | The Rust struct representing a database row. Fields map to database columns. |
| Entity Struct | A unit struct (usually named Entity) that serves as the entry point for queries. |
| Column Enum | Defines the available columns in the entity, used for filtering and sorting. |
| PrimaryKey Enum | Defines the primary key(s) for the entity. |
| Relation Enum | Defines the relationships between this entity and others. |
| ActiveModel | A mutable version of the Model used for insertions and updates. |
Sources: sea-orm-codegen/src/entity/writer.rs:468-522, sea-orm-codegen/src/entity/base_entity.rs:13-21
Data Structure Relationship
The following diagram illustrates how the different components of a SeaORM entity relate to each other within a module.
Sources: CLAUDE.md:25-37, src/lib.rs:88-100
Relationship Modeling (2.0 Format)
SeaORM 2.0 simplifies relations by defining them directly as fields within the Model struct using specific wrapper types like HasOne<T> and HasMany<T>. This replaces the legacy requirement of manual trait implementations for relationships.
Relation Types and Attributes
Relationships are configured using the #[sea_orm(...)] attribute on fields within the Model struct.
- Has-One: Used for 1-1 relationships where the current entity owns the relation.
- Has-Many: Used for 1-N relationships.
- Belongs-To: Used for the child side of a relationship, requiring explicit
fromandtocolumn mapping. - Many-to-Many: Achieved using
viato specify a junction table. - Self-Referential: Defined using the
self_refattribute, often withviafor junction-based self-relations (e.g., followers).
Sources: CLAUDE.md:42-63, sea-orm-codegen/src/entity/writer/dense.rs:141-205
Junction Table Definition
Junction tables for Many-to-Many relationships typically use composite primary keys and multiple belongs_to relations.
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "post_tag")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub post_id: i32,
#[sea_orm(primary_key, auto_increment = false)]
pub tag_id: i32,
#[sea_orm(belongs_to, from = "post_id", to = "id")]
pub post: Option<super::post::Entity>,
#[sea_orm(belongs_to, from = "tag_id", to = "id")]
pub tag: Option<super::tag::Entity>,
}
Sources: CLAUDE.md:67-80, sea-orm-sync/examples/quickstart/src/main.rs:107-122
Code Generation Formats
The sea-orm-codegen tool supports multiple output formats to suit different development styles. The format is selected via the EntityFormat enum.
| Format | Description |
|---|---|
| Dense | The modern 2.0 format where all metadata (columns, relations) is defined within the Model struct using attributes. |
| Compact | A transitional format that separates the Model struct and Relation enum but keeps code minimal. |
| Expanded | Detailed format where every trait implementation is explicitly written out in the generated files. |
| Frontend | Tailored for environments where only model definitions are needed without database logic. |
Sources: sea-orm-codegen/src/entity/writer.rs:77-83, sea-orm-codegen/src/entity/writer.rs:245-285
Dense vs. Compact Implementation
The code generation logic varies significantly between formats. The dense writer packs logic into the model struct, while compact distributes it across several trait implementations.
Column Types and Attributes
Columns are inferred from the fields of the Model struct. SeaORM maps Rust types to database-specific types automatically, but behavior can be customized using attributes.
Column Mapping Rules
- Primary Keys: Annotated with
#[sea_orm(primary_key)]. If it's a composite key, multiple fields are marked. - Auto-increment: By default, primary keys are auto-incrementing unless
auto_increment = falseis specified. - Uniqueness: Marked with
#[sea_orm(unique)]. - Nullability: Inferred from
Option<T>. Indenseformat, non-optional fields can be markednullableexplicitly if needed. - Large Strings: On MySQL/MSSQL,
Stringmaps toVARCHAR(255). Use#[sea_orm(column_type = "Text")]for longer content.
Sources: CLAUDE.md:129-146, sea-orm-codegen/src/entity/writer/dense.rs:59-88
Column Trait and Expressions
The ColumnTrait provides the API for building expressions using columns. In SeaORM 2.0, developers are encouraged to use the COLUMN constant for type-safe queries.
// Type-safe column reference (2.0)
user::Entity::find().filter(user::COLUMN.name.contains("Bob"))
Sources: CLAUDE.md:84-90, sea-orm-sync/src/entity/column.rs:88-112
Summary
Defining Entities and Models in SeaORM provides a type-safe abstraction over relational databases. By utilizing the new 2.0 format, developers can describe complex object graphs with minimal boilerplate, relying on the #[sea_orm::model] attribute to bridge the gap between Rust structures and SQL schemas. The architecture supports both a "Schema First" approach through migrations and an "Entity First" approach via the Schema Registry, allowing flexible development workflows across different database backends.
Sources: src/lib.rs:125-138, sea-orm-sync/src/lib.rs:125-138