Basic Relations (1-1, 1-N)
Relevant source files
The following files were used as context for generating this wiki page:
Basic relations in SeaORM 2.0 facilitate the modeling of database associations between entities using a high-level, conceptual approach. These relations primarily consist of One-to-One (1-1) and One-to-Many (1-N) mappings, which are defined directly within the Model struct using specific attribute macros.
SeaORM 2.0 introduces a simplified entity format where relations are represented as fields on the model, replacing the older pattern of separate Relation enums and Related trait implementations. This approach allows for compile-time type safety and an ergonomic API for loading and persisting nested object graphs.
Sources: CLAUDE.md:14-16, sea-orm-sync/src/lib.rs:25-27
Relation Architecture in 2.0
In the SeaORM 2.0 format, relations are defined using the #[sea_orm(has_one)], #[sea_orm(has_many)], and #[sea_orm(belongs_to)] attributes. These attributes inform the ORM how to perform SQL joins or use the data loader to fetch related records without encountering the N+1 problem.
Key Components
| Component | Description |
|---|---|
HasOne<T> | Represents a 1-1 relationship or the "parent" side of a BelongsTo relationship. |
HasMany<T> | Represents a 1-N relationship where one record is associated with a collection of others. |
#[sea_orm(belongs_to)] | Defines the foreign key mapping from the child entity back to the parent. |
Entity Loader | The engine that intelligently chooses between JOIN (for 1-1) and Data Loader (for 1-N). |
Sources: CLAUDE.md:38-51, sea-orm-sync/src/lib.rs:136-140
Entity Relationship Structure
The following diagram illustrates how basic 1-1 and 1-N relations are structured between a User, their Profile, and their Posts.
The diagram shows a typical setup where a User has one Profile (1-1) and multiple Posts (1-N).
Sources: sea-orm-sync/examples/quickstart/src/main.rs:5-75
One-to-One (1-1) Relations
A One-to-One relation exists when a single record in one table is associated with exactly one record in another table. In SeaORM, this is typically implemented using a has_one attribute on the primary entity and a belongs_to attribute on the related entity.
Implementation Logic
- Primary Side: Use
#[sea_orm(has_one)]with the typeHasOne<RelatedEntity::Entity>. - Related Side: Use
#[sea_orm(belongs_to, from = "local_id", to = "remote_id")]to specify the foreign key constraint.
// User side (1-1)
#[sea_orm(has_one)]
pub profile: HasOne<super::profile::Entity>,
// Profile side (Belongs To)
#[sea_orm(belongs_to, from = "user_id", to = "id")]
pub user: HasOne<super::user::Entity>,
Sources: CLAUDE.md:38-40, CLAUDE.md:46-47
Data Flow: Loading 1-1
When using the Entity Loader, 1-1 relations are fetched using a SQL JOIN operation.
Sources: sea-orm-sync/src/lib.rs:149-151
One-to-Many (1-N) Relations
A One-to-Many relation allows one record in an entity to be associated with multiple records in another entity. This is defined using #[sea_orm(has_many)] on the "one" side and #[sea_orm(belongs_to)] on the "many" side.
Implementation Logic
The "one" side stores a HasMany<T> collection, while the "many" side contains a foreign key pointing back to the "one" side.
// User side (1-N)
#[sea_orm(has_many)]
pub posts: HasMany<super::post::Entity>,
// Post side (Belongs To)
#[sea_orm(belongs_to, from = "user_id", to = "id")]
pub author: HasOne<super::user::Entity>,
Sources: sea-orm-sync/examples/quickstart/src/main.rs:16-55
Batch Loading (N+1 Prevention)
For 1-N relations, SeaORM uses a batch data loader. Instead of joining, it executes a separate query using an IN clause to fetch all related children for the parents found in the initial query.
Sources: sea-orm-sync/src/lib.rs:152-154
Code Generation and Transformation
SeaORM provides tools to automatically generate these relations from database schemas. The EntityTransformer analyzes foreign key constraints to determine the relation type.
Transformation Rules
- If a foreign key column is marked as
UNIQUE, the transformer identifies it as aHasOnerelation. - If the foreign key column is not unique, it is identified as a
HasManyrelation. - Self-referencing relations are detected when the reference table matches the current table name.
Sources: sea-orm-codegen/src/entity/transformer.rs:164-177
Writer Logic (Dense Format)
The EntityWriter in dense mode generates the model fields based on these identified relations. It automatically pluralizes field names for HasMany relations and handles column mapping for belongs_to attributes.
Sources: sea-orm-codegen/src/entity/writer/dense.rs:152-184
Summary
Basic relations in SeaORM 2.0 provide a typed, efficient way to manage database associations. By utilizing HasOne and HasMany wrappers directly on model structs, developers gain compile-time checks and an intuitive API. The Entity Loader further optimizes these relations by choosing the most efficient fetching strategy—joins for 1-1 and batch loading for 1-N—to ensure high performance even with complex, nested object graphs.
Sources: CLAUDE.md:92-108, sea-orm-sync/src/lib.rs:135-141