Customizing Derive Macros & Attributes
Relevant source files
The following files were used as context for generating this wiki page:
Customizing derive macros and attributes in SeaORM 2.0 allows developers to control how Rust structures map to database schemas, how they are serialized, and how code generation behaves. This system is primarily driven by procedural macros in the sea-orm-macros crate and configuration options in the sea-orm-codegen toolset.
The scope includes mapping table names, column types, primary keys, and relations through the #[sea_orm(...)] attribute, as well as integrating with third-party libraries like serde for JSON serialization. This flexibility supports both "Database-First" workflows (via code generation) and "Entity-First" workflows where manual customizations are preserved through code merging.
Sources: CLAUDE.md:16-35, sea-orm-macros/src/derives/entity_model.rs:72-130
Entity and Model Attributes
Attributes at the struct level control the high-level mapping of a Rust model to a database table. The DeriveEntityModel macro parses these attributes to generate the corresponding Entity struct and EntityName implementation.
Key Struct-Level Attributes
The following attributes are supported within #[sea_orm(...)] at the struct level:
| Attribute | Purpose | Implementation Detail |
|---|---|---|
table_name | Specifies the database table name. | Parsed as LitStr. |
schema_name | Specifies the database schema. | Optional; defaults to None. |
comment | Adds a comment to the table metadata. | Generated in EntityName::comment(). |
rename_all | Changes case style for all columns. | Supports CamelCase, snake_case, etc. |
table_iden | Generates an identifier for the table. | Creates a Table variant in Column. |
Sources: sea-orm-macros/src/derives/entity_model.rs:88-105
Serde Integration
SeaORM entities can be customized for JSON serialization using #[serde(...)] attributes. The macros specifically look for rename_all at the struct level to ensure that database column mapping aligns with JSON field names if needed.
Sources: sea-orm-macros/src/derives/entity_model.rs:72-86
Column Customization
Column-level attributes allow for granular control over database types, constraints, and behavior during CRUD operations.
The diagram shows how field attributes are processed by macros to generate database definitions and model mappings.
Sources: sea-orm-macros/src/derives/entity_model.rs:163-330
Column Attribute Parameters
primary_key: Marks a field as the primary key. If a single field is marked,auto_incrementdefaults to true unless specified otherwise.column_type: Overrides the inferred database type (e.g.,Text,Decimal(10,2)). Note that forDeriveValueType, manual annotation is considered an anti-pattern as types are inferred from the inner type.default_value/default_expr: Sets static or dynamic (SQL expression) defaults for the column.select_as/save_as: Customizes the SQL casting during selection or insertion.ignore: Prevents the field from being mapped to a database column.
Sources: sea-orm-macros/src/derives/entity_model.rs:194-250, CLAUDE.md:104-118
ActiveModel and ActiveValue Mapping
The DeriveActiveModel macro generates an ActiveModel struct where every field is wrapped in an ActiveValue<T>. This enables partial updates by tracking which fields are "Set", "Unchanged", or "NotSet".
ActiveModel Generation Logic
- Field Filtering: Fields marked with
#[sea_orm(ignore)]are skipped. - Naming: Field names are converted to PascalCase for the
Columnenum variants but retained in original form for theActiveModelstruct fields. - Trait Implementations: Automatically implements
From<Model>,IntoActiveModel, andActiveModelTrait.
Sources: sea-orm-macros/src/derives/active_model.rs:24-60, sea-orm-macros/src/derives/active_model.rs:94-115
ActiveModel Trait Methods
| Method | Logic |
|---|---|
take | Swaps the field value with NotSet and returns the old value. |
get | Returns a clone of the field's ActiveValue. |
try_set | Attempts to set a value, performing type conversion; returns DbErr on failure. |
default_values | Populates the model using DefaultActiveValue traits. |
Sources: sea-orm-macros/src/derives/active_model.rs:141-190
Code Generation and Merging
The sea-orm-codegen crate manages the generation of entity files and provides a mechanism to merge new generated code with existing manual customizations.
Entity Format Options
The EntityWriter supports several formats via the EntityFormat enum:
Compact: The standard 2.0 format where relations are defined on theModel.Expanded: Separate modules for entities, columns, and relations.Dense: A condensed single-file representation.Frontend: Optimized for client-side use (e.g., without database-specific traits).
Sources: sea-orm-codegen/src/entity/writer.rs:72-80, CLAUDE.md:16-25
The Merge Workflow
When entities are re-generated, the Merger logic ensures that manual additions (like extra derive macros, custom impl blocks, or additional use statements) are not lost.
The sequence diagram illustrates how the sea-orm-codegen merger combines existing file state with new generator output to prevent regression of custom logic.
Sources: sea-orm-codegen/src/merge/mod.rs:56-120
Attributes Merging Rules
- Derives: New and old
#[derive(...)]paths are merged into a unique set. - Doc Comments: Existing doc comments are preserved and combined with generated ones.
- Conflict Resolution: If a conflict occurs between a manual attribute and a generated one, the existing manual attribute is prioritized to preserve developer intent.
Sources: sea-orm-codegen/src/merge/mod.rs:175-220, sea-orm-codegen/src/merge/mod.rs:240-270
Summary of Attribute Usage
| Level | Attribute | Example |
|---|---|---|
| Struct | table_name | #[sea_orm(table_name = "users")] |
| Struct | model_ex | #[sea_orm(model_ex = ModelEx)] |
| Field | primary_key | #[sea_orm(primary_key)] |
| Field | auto_increment | #[sea_orm(auto_increment = false)] |
| Field | column_type | #[sea_orm(column_type = "Text")] |
| Field | enum_name | #[sea_orm(enum_name = "UserStatus")] |
| Field | indexed | #[sea_orm(indexed)] |
Sources: sea-orm-macros/src/derives/entity_model.rs:114-125, sea-orm-macros/src/derives/entity_model.rs:194-245
Customizing derive macros and attributes in SeaORM 2.0 provides a robust interface between Rust's type system and relational databases. By utilizing the #[sea_orm(...)] attribute system, developers can fine-tune table mapping, column constraints, and serialization behavior. The combination of powerful procedural macros and a smart code-merging generator ensures that entities remain maintainable even as database schemas evolve.