Vendor dependencies

This commit is contained in:
2026-08-01 16:11:49 +03:00
parent 7f139a0241
commit 6b5e7f0f8b
29706 changed files with 9575646 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
## Release Notes: SeaORM 2.0.0-rc.20
*(since 2.0.0-rc.19)*
### New Features
**Allow more stringy newtypes in `DeriveValueType`** (#2831)
- Produce syntax-aware attribute errors in `DeriveValueType` macro
- Allow `value_type` attr for named field structs in `DeriveValueType`
- Assume no derive attributes means `DeriveValueTypeStruct`
**Many-to-many self-referencing relation** (#2823)
- Add primary_key check to `DeriveEntityModel`
- Support `RelatedSelfVia` and `self_ref` in dense entity format
- Support `self_ref` on compact_model and in reverse
- Loader support for self via in reverse
**ActiveModelEx: support `self_ref`**
ActiveModelEx now supports self-referencing relations.
**Add nullable column types**
Support for nullable column types added.
### Bug Fixes
**Fix missing casts when returning one** (#2825)
Fixed missing type casts when using `returning_one` / `returning_all`.
**Temp fix MySQL JSON equals**
Workaround for MySQL JSON equality comparison issues.
**Automatically convert `eq(None)` to `IS NULL`** (#2826)
`eq(None)` is now correctly translated to `IS NULL` in SQL.
**Fix compile error when postgres-vector is enabled** (#2821)
Resolved compilation failure with the `postgres-vector` feature.
### Improvements
- Entity Loader: move `EntityLoaderWithParam` trait to be owned by user for better blanket impl support
- Built with SeaORM: Add FirstLook.gg (#2828)
+31
View File
@@ -0,0 +1,31 @@
## Release Notes: SeaORM 2.0.0-rc.21
*(since 2.0.0-rc.20)*
### New Features
**Rusqlite / sea-orm-sync** (#2847)
- New `sea-orm-sync` crate for synchronous SQLite via rusqlite
- Stream and transaction support
- Integration with `sea-schema-sync`
**Add `--banner-version` to CLI** (#2836)
CLI now supports a `--banner-version` flag.
**Add `exists` method to `PaginatorTrait`** (#2623)
`PaginatorTrait` now includes an `exists` method for efficient existence checks.
### Bug Fixes
**Respect `#[serde(rename)]` in `ActiveModel::from_json`** (#2842)
`ActiveModel::from_json` now correctly respects `#[serde(rename)]` and `#[serde(rename_all)]` attributes when deserializing JSON.
### Improvements
- Reduce Vec allocations (#2835)
- Add taplo for TOML formatting (#2844)
- SeaORM sync example and preparation for `sea-orm-sync` crate
+38
View File
@@ -0,0 +1,38 @@
## Release Notes: SeaORM 2.0.0-rc.22
*(since 2.0.0-rc.21)*
### New Features
**`DatabaseExecutor` unified executor type** (#2839)
Added a unified `DatabaseExecutor` type that wraps either a `&DatabaseConnection` or `&DatabaseTransaction`. This moves the `SchemaManagerConnection` pattern from `sea-orm-migration` into sea-orm core, providing:
- `DatabaseExecutor` enum for unified handling of connections and transactions
- `IntoDatabaseExecutor` trait for ergonomic conversions
- `SchemaManagerConnection` type alias for backward compatibility
- `SchemaManagerConnectionExt` trait for migration-specific methods
### Bug Fixes
*None in this release.*
### Improvements
**Refactor Value array** (#2849)
Refactored the internal `Value` array handling for improved consistency and maintainability.
**Refactor CI** (#2859)
- Parallelized test compilation for faster CI runs
- Updated `actions/cache` to v5
- Fixed cache keys
**sea-orm-sync example**
Added and improved the `sea-orm-sync` example.
**Update examples**
Updated example code across the repository.
+45
View File
@@ -0,0 +1,45 @@
## Release Notes: SeaORM 2.0.0-rc.23
*(since 2.0.0-rc.22)*
### New Features
**`DeriveValueType` implements `IntoActiveValue`** (#2868)
`DeriveValueType` now automatically implements `IntoActiveValue`, so custom value types can be used directly when building ActiveModels without additional boilerplate.
**`IntoActiveValue` for more types**
`IntoActiveValue` is now implemented for additional standard types, improving ergonomics when setting ActiveModel fields.
### Bug Fixes
**Fix sea-orm-sync**
Fixed issues in the `sea-orm-sync` crate.
**Fix sync**
Fixed sync-related bugs.
**Fix tests**
Resolved failing tests.
**Insert many on conflict do nothing returning** (#2389)
Added test coverage and fixes for `insert_many` with `on_conflict_do_nothing` and `returning` clauses.
### Improvements
**Remove `NotU8` trait** (#2868)
The `NotU8` trait has been removed. `DeriveValueType` now handles type constraints internally, simplifying the derive macro.
**Remove `bigdecimal` from default features**
The `bigdecimal` dependency is no longer included in default features, reducing the default dependency footprint. Enable it explicitly if needed.
**CI improvements**
Various CI fixes and improvements.
+8
View File
@@ -0,0 +1,8 @@
## Release Notes: SeaORM 2.0.0-rc.24
*(since 2.0.0-rc.23)*
### Improvements
- Bumped `sea-query` to 1.0.0-rc.27
- Updated example projects to use the new release
+18
View File
@@ -0,0 +1,18 @@
## Release Notes: SeaORM 2.0.0-rc.25
*(since 2.0.0-rc.24)*
### Bug Fixes
**Restore value system**
Restored the value system across the core crate, drivers (MySQL, PostgreSQL, SQLite), and entity/column types. Refactored executor and query handling for consistency.
**Fix sea-orm-sync**
Aligned `sea-orm-sync` with the restored value system changes in the main crate. Updated drivers, entity types, and executor/query logic to match.
### Improvements
- Bumped `sea-query` to 1.0.0-rc.28
- Updated example projects to use the new release
+9
View File
@@ -0,0 +1,9 @@
## Release Notes: SeaORM 2.0.0-rc.26
*(since 2.0.0-rc.25)*
### New Features
**PostgreSQL legacy serial primary key option**
Added the `postgres-use-serial-pk` feature flag to use legacy `serial` / `bigserial` types for auto-increment primary keys instead of `GENERATED BY DEFAULT AS IDENTITY`. Enable with `postgres-use-serial-pk` in your `Cargo.toml` if you need compatibility with older PostgreSQL setups or tooling.
+9
View File
@@ -0,0 +1,9 @@
## Release Notes: SeaORM 2.0.0-rc.27
*(since 2.0.0-rc.26)*
### Improvements
**DeriveValueType implements NotU8**
`DeriveValueType` now also implements `sea_query::postgres_array::NotU8`, enabling custom value types to work with PostgreSQL array columns. This is auto-generated when the `postgres-array` feature is enabled. Remove any manual `NotU8` implementations on your custom types to avoid conflicts.
+37
View File
@@ -0,0 +1,37 @@
## Release Notes: SeaORM 2.0.0-rc.28
*(since 2.0.0-rc.27)*
### New Features
**`sqlx-all` feature in sea-orm-migration** (#2887)
Added `sqlx-all` feature flag to `sea-orm-migration` for compatibility with sqlx's all-database feature.
**`set_if_not_equals_and` on ActiveValue** (#2888)
Added `set_if_not_equals_and` method to `ActiveValue` for conditional updates based on value comparison.
**Set auto_increment to false for String/Uuid primary keys by default** (#2881)
Macros now set `auto_increment = false` by default when the primary key is `String` or `Uuid`, avoiding incorrect schema generation.
### Bug Fixes
**Postgres: combine SET TRANSACTION statements** (#2893)
Combined `SET TRANSACTION ISOLATION LEVEL` and `ACCESS MODE` into a single statement for PostgreSQL, fixing transaction setup.
### Improvements
**Debug log for entity registry** (#2900)
Added debug logging for entity registry operations to aid troubleshooting.
**Deprecate do_nothing and on_empty_do_nothing** (#2883)
Deprecated `do_nothing` and `on_empty_do_nothing` on insert operations. Added documentation and tests for the deprecation path.
**Add Rustify to COMMUNITY.md** (#2898)
Added Rustify bot to the community bots section, covering multi-source lyrics, AI analysis, real-time profanity detection, and auto-skip features.
+57
View File
@@ -0,0 +1,57 @@
## Release Notes: SeaORM 2.0.0-rc.29
*(since 2.0.0-rc.28)*
### New Features
**Tracing spans for database operations** (#2885)
Added `ObservabilityHook` and `with_db_span!` macro for distributed tracing support. Database operations and transactions emit tracing spans when the `tracing-spans` feature is enabled.
**Wrapper type for storing UUIDs as TEXT** (#2914)
Added a wrapper type for storing `Uuid` values as TEXT columns.
**`Insert::try_insert` method**
Added `try_insert` to the `Insert` trait for fallible insert operations.
**Filter relations outside generation set** (#2913)
Codegen now filters relations that fall outside the generation set.
### Bug Fixes
**Allow LEFT JOIN to produce None for nested models** (#2845)
Fixed handling of nested `Option<Model>` in `FromQueryResult` when using LEFT JOINs, so optional nested models correctly produce `None` when no related row exists.
**Fix DeriveIntoActiveModel** (#2926)
Fixed `DeriveIntoActiveModel` derive macro; added test coverage.
**Fix tracing spans visibility** (#2925)
Corrected tracing span visibility for database operations.
**Fix derive enums without per-case rename** (#2922)
Fixed codegen for enums that do not use per-variant `rename` attributes. Addresses [#2921](https://github.com/SeaQL/sea-orm/issues/2921).
**Fix renaming enum variants starting with digits** (#2905)
Enum variants that start with digits are now correctly renamed during codegen.
**Revert multi-argument extra attribute support** (#2915)
Reverted the multi-argument extra attribute codegen change (#2560) due to incorrect test input parsing that caused `syn` to panic. The attribute format should split arguments by `,`.
**Add missing lifetime hint to `EntityName::table_name`** (#2907)
Added the missing lifetime hint to fix compilation in certain contexts.
### Improvements
**Optimize exists** (#2909)
Improved performance of the `exists` query.
+13
View File
@@ -0,0 +1,13 @@
## Release Notes: SeaORM 2.0.0-rc.30
*(since 2.0.0-rc.29)*
### Improvements
**Dependency updates**
Bumped `sea-query` dependency.
**Examples**
Updated examples.
+45
View File
@@ -0,0 +1,45 @@
## Release Notes: SeaORM 2.0.0-rc.31
*(since 2.0.0-rc.30)*
### New Features
**`ne_all` for `Condition`**
Added `ne_all` to complement `eq_any`, allowing negation of multiple values in conditions.
**Typed column for `TextUuid`** (#2717)
Added typed column support for `TextUuid` type.
**Custom derives for `Model` and `ModelEx`** (#2933)
Macros now support `model_attrs` and `model_ex_attrs` to pass custom derives and attributes to the generated `Model` and `ModelEx` structs. Enables customization such as TypeScript interface names when using `ts-rs`:
```rust
#[sea_orm::model]
#[derive(TS, ...)]
#[sea_orm(model_attrs(ts(rename = "Fruit")))]
#[sea_orm(model_ex_attrs(ts(rename = "FruitEx")))]
struct Model { ... }
```
### Bug Fixes
**`COUNT(*)` overflow on MySQL and SQLite** (#2944)
`COUNT(*)` now returns `i64` on all backends. MySQL's `COUNT(*)` returns `BIGINT` (64-bit); previously it was read as `i32`, which could overflow for large datasets.
**Proxy error handling** (#2935)
Fixed proxy error handling.
### Improvements
**Relaxed trait bounds for `eq_any` / `ne_all`**
Relaxed trait bounds on `eq_any` and `ne_all` for broader compatibility. Depends on latest `sea-query`.
**Raw string hashes** (#2381)
Refactored to remove raw string hashes for improved readability.
+17
View File
@@ -0,0 +1,17 @@
## Release Notes: SeaORM 2.0.0-rc.32
*(since 2.0.0-rc.31)*
### New Features
**`MigratorTrait` with `self`** (#2806)
`MigratorTrait` now uses `MigratorTraitSelf` with a shim, enabling migrator implementations that take `self` by reference.
**PostgreSQL `application_name`**
Added support for setting `application_name` when connecting to PostgreSQL.
### Improvements
- Updated examples
+45
View File
@@ -0,0 +1,45 @@
## Release Notes: SeaORM 2.0.0-rc.34
*(since 2.0.0-rc.32)*
### New Features
**Arrow / Parquet support** (#2957)
- Extracted `sea-orm-arrow` into a dedicated crate
- Added `ArrowSchema`, `DeriveArrowSchema` for entity-to-Arrow conversion
- Support decimal with different formats and timestamp with different timezone/resolution
- Added `ActiveModel::from_arrow` for creating ActiveModels from Arrow arrays
- Parquet example added
- Arrow support in `sea-orm-sync`
**`DeriveValueType`: `try_from_u64`** (#2958)
`DeriveValueType` now derives `TryFromU64` for custom value types.
**Derive `Clone` for topologies** (#2954)
Topology types can now derive `Clone`.
**`preserve-user-modifications` experimental flag** (#2964)
Added experimental `preserve-user-modifications` option for schema sync; default is `false`.
**Optional `sea-schema`**
`sea-schema` can be optional in some configurations.
### Bug Fixes
**Don't create redundant unique indexes** (#2950)
Fixed creation of redundant unique indexes on PostgreSQL and SQLite when a column is already unique. Fixes #2873.
**Typo: "exsiting" → "existing"** (#2956)
### Improvements
- Refactored `sea-orm-arrow`; upgraded to Arrow 57; removed direct Arrow dependency
- Improved docs for `DeriveValueType` (#2958)
- Split up test suite by creating only needed tables per test
- Support SeaORM X in `sea-orm-sync`
+159
View File
@@ -0,0 +1,159 @@
## Release Notes: SeaORM 2.0.0-rc.35
*(since 2.0.0-rc.34)*
### New Features
**SQLite Transaction Modes** (#2932)
Added `begin_with_options` to `TransactionTrait`, allowing you to specify SQLite transaction modes (`DEFERRED`, `IMMEDIATE`, `EXCLUSIVE`), along with isolation level and access mode for other backends. Works for both sqlx-sqlite and rusqlite.
```rust
use sea_orm::{TransactionTrait, TransactionOptions, SqliteTransactionMode};
let txn = db.begin_with_options(TransactionOptions {
sqlite_transaction_mode: Some(SqliteTransactionMode::Immediate),
..Default::default()
}).await?;
```
Nested transactions correctly fall back to `SAVEPOINT` regardless of the mode.
**Extend `DeriveIntoActiveModel`** (#2961)
`DeriveIntoActiveModel` now supports `set`, `default`, `ignore`, `exhaustive`, and custom `active_model` path attributes for fine-grained control when converting "form" or "input" structs into ActiveModels.
**`set`** — always set fields not present on the struct:
```rust
#[derive(DeriveIntoActiveModel)]
#[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "None"))]
struct NewFruit {
name: String,
// cake_id is not on the struct, but will always be Set(None)
}
NewFruit { name: "Apple".into() }.into_active_model()
// => ActiveModel { id: NotSet, name: Set("Apple"), cake_id: Set(None) }
```
Multiple `set` entries can be combined or split across attributes:
```rust
#[derive(DeriveIntoActiveModel)]
#[sea_orm(
active_model = "fruit::ActiveModel",
set(name = "String::from(\"cherry\")", cake_id = "None")
)]
struct IdOnlyFruit {
id: i32,
}
IdOnlyFruit { id: 1 }.into_active_model()
// => ActiveModel { id: Set(1), name: Set("cherry"), cake_id: Set(None) }
```
**`default`** — fallback value when an `Option<T>` field is `None`:
```rust
#[derive(DeriveIntoActiveModel)]
#[sea_orm(active_model = "fruit::ActiveModel")]
struct NewFruit {
#[sea_orm(default = "String::from(\"Unnamed\")")]
name: Option<String>,
}
NewFruit { name: Some("Apple".into()) }.into_active_model()
// => ActiveModel { id: NotSet, name: Set("Apple"), cake_id: NotSet }
NewFruit { name: None }.into_active_model()
// => ActiveModel { id: NotSet, name: Set("Unnamed"), cake_id: NotSet }
```
Bare `#[sea_orm(default)]` (without a value) uses `Default::default()` as the fallback. This also works with custom enum types that implement `Into<Option<T>>`.
**`ignore`** — exclude struct fields from the ActiveModel:
```rust
#[derive(DeriveIntoActiveModel)]
#[sea_orm(active_model = "fruit::ActiveModel")]
struct NewFruit {
name: String,
cake_id: i32,
#[sea_orm(ignore)]
_extra: String, // not mapped to ActiveModel
}
```
**`exhaustive`** — require all ActiveModel fields to be either on the struct or in `set(...)`:
```rust
#[derive(DeriveIntoActiveModel)]
#[sea_orm(active_model = "fruit::ActiveModel", exhaustive, set(cake_id = "None"))]
struct FullFruit {
id: i32,
name: String,
// cake_id is covered by set(...), so all fields are accounted for
}
```
**Combining everything** — `set` + `default` + `ignore` + `exhaustive`:
```rust
#[derive(DeriveIntoActiveModel)]
#[sea_orm(active_model = "fruit::ActiveModel", exhaustive, set(cake_id = "None"))]
struct NewFruit {
id: i32,
#[sea_orm(default = "String::from(\"Unnamed\")")]
name: Option<String>,
}
NewFruit { id: 1, name: Some("Apple".into()) }.into_active_model()
// => ActiveModel { id: Set(1), name: Set("Apple"), cake_id: Set(None) }
NewFruit { id: 2, name: None }.into_active_model()
// => ActiveModel { id: Set(2), name: Set("Unnamed"), cake_id: Set(None) }
```
**`IntoSimpleExpr` for `FunctionCall`** (#2822)
`FunctionCall` now implements `IntoSimpleExpr`, so function calls can be used directly in select expressions and filters without wrapping in `SimpleExpr`.
**Arrow: Support `Decimal64` and Fixed-Size Binary** (#2957)
- Decimal columns with precision <= 18 now map to Arrow `Decimal64` (was always `Decimal128`)
- Precision 19-38 maps to `Decimal128`, above 38 to `Decimal256`
- Added `FixedSizeBinary(N)` support via `#[sea_orm(arrow_byte_width = N)]`
- Added `BinaryArray` / `LargeBinaryArray` / `FixedSizeBinaryArray` to `Value::Bytes` conversion
**Optional `time` crate for Migrations** (#2865)
Migrations can now use the `time` crate instead of `std::time::SystemTime` for timestamps, enabling compilation to WASM targets. Activate with the `with-time` feature on `sea-orm-migration`.
**OpenTelemetry `SpanKind::Client`** (#2937)
The `db_span!` macro now emits `otel.kind = "client"`, ensuring database spans are properly recognized as client spans by APM tools (Datadog, Jaeger, etc.).
### Bug Fixes
**Fix unique column in schema sync** (#2971)
Columns marked with `#[sea_orm(unique)]` are now correctly handled by the schema sync/diff builder, generating proper unique constraints instead of being silently ignored.
**Fix `DeriveArrowSchema` with split attributes** (#2973)
Fixed a compilation error when `#[sea_orm(...)]` attributes were split across multiple lines on the same field (e.g. `#[sea_orm(primary_key)]` and `#[sea_orm(auto_increment = false)]` separately). The macro now properly consumes attributes it doesn't recognize.
**Map internal error types properly**
Internal errors from the schema builder are now mapped to the correct `DbErr` variants instead of being lost or mistyped.
### Improvements
**Pi Spigot Example**
The `sea-orm-sync` pi spigot example has been refactored into a tutorial-style example with:
- OOP `PiSpigot` struct with state machine pattern (`new` / `step` / `finalize` / `to_state` / `from_state`)
- `clap` CLI with `--digits`, `--checkpoint`, and `--db` flags
- Comprehensive tests against 1000 known digits of pi, including three-phase checkpoint/resume
- Tutorial README demonstrating how to add SQLite persistence to any program
+51
View File
@@ -0,0 +1,51 @@
## Release Notes: SeaORM 2.0.0-rc.36
*(since 2.0.0-rc.35)*
### New Features
**Per-Migration Transaction Control** (#2980)
Previously, all Postgres migrations ran inside a single batch transaction, while MySQL and SQLite ran without one. This was an all-or-nothing approach with no way to opt out for individual migrations (e.g. `CREATE INDEX CONCURRENTLY` on Postgres requires running outside a transaction).
`MigrationTrait` now has a `use_transaction()` method to control this per migration:
```rust
impl MigrationTrait for Migration {
fn use_transaction(&self) -> Option<bool> {
Some(false) // opt out of automatic transaction
}
}
```
- `None` (default): follow backend convention — Postgres uses a transaction, MySQL/SQLite do not
- `Some(true)`: force a transaction on any backend
- `Some(false)`: disable automatic transaction wrapping
For migrations that opt out, `SchemaManager::begin()` and `SchemaManager::commit()` allow manual transaction control within the migration body:
```rust
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// DDL in a transaction
let m = manager.begin().await?;
m.create_table(
Table::create()
.table("my_table")
.col(pk_auto("id"))
.col(string("name"))
.to_owned(),
).await?;
m.commit().await?;
// Non-transactional DDL
manager.get_connection()
.execute_unprepared("CREATE INDEX CONCURRENTLY idx_name ON my_table (name)")
.await?;
Ok(())
}
```
Core changes:
- Added `OwnedTransaction` variant to `DatabaseExecutor`, enabling `SchemaManager` to own a transaction
- Added `DatabaseExecutor::is_transaction()` for runtime introspection
- Each migration is now wrapped individually rather than in a batch
+71
View File
@@ -0,0 +1,71 @@
## Release Notes: SeaORM 2.0.0-rc.37
*(since 2.0.0-rc.36)*
### New Features
**ER Diagram Generation** (`sea-orm-cli generate entity --er-diagram`)
`sea-orm-cli` can now generate a [Mermaid](https://mermaid.js.org/) ER diagram alongside the entity files. Pass `--er-diagram` to write `entities.mermaid` into the output directory:
```sh
sea-orm-cli generate entity -u postgres://... -o src/entity --er-diagram
```
The diagram annotates columns with `PK`, `FK`, and `UK` markers and renders all relations — including many-to-many via junction tables — as Mermaid `erDiagram` syntax. Example output:
```
erDiagram
user {
int id PK
varchar name
varchar email UK
int parent_id FK
}
post {
int id PK
text title
int user_id FK
}
user }o--|| user : "parent_id"
post }o--|| user : "user_id"
post }o--o{ tag : "[post_tag]"
```
**PostgreSQL Statement Timeout** (`ConnectOptions::statement_timeout`)
`ConnectOptions` now accepts a `statement_timeout` for PostgreSQL connections. The timeout is set via the connection options at connect time (no extra round-trip) and causes the server to abort any statement that exceeds the duration:
```rust
ConnectOptions::new(DATABASE_URL)
.statement_timeout(Duration::from_secs(30))
.to_owned()
```
Has no effect on MySQL or SQLite connections.
**SQLite `?mode=` URL Parameter Support** (#2987)
The rusqlite driver now parses the `?mode=` query parameter from SQLite connection URLs, matching the behaviour of the sqlx SQLite driver:
| Mode | Behaviour |
|---|---|
| `rwc` (default) | Read-write, create if not exists |
| `rw` | Read-write, must exist |
| `ro` | Read-only |
| `memory` | In-memory database |
```rust
// Open an existing database read-only
let db = Database::connect("sqlite:./data.db?mode=ro").await?;
```
Unsupported parameters or unknown mode values return a `DbErr::Conn` error.
### Bug Fixes
**`no-default-features` compile errors with `mac_address` and `proxy`** (#2992)
- `with-mac_address` feature: added missing `TryGetable` impls, `try_from_u64` impl, postgres array support, and `with-json` serde flag
- `proxy` feature: removed an accidental hard dependency on `serde_json` (now only activated via `with-json`)
- Fixed `cfg` guards on JSON/JSONB proxy row handling to require `with-json`
+84
View File
@@ -0,0 +1,84 @@
## Release Notes: SeaORM 2.0.0-rc.38
*(since 2.0.0-rc.37)*
### New Features
**`find_both_related()` — required inner join loader** (#2997)
A new `find_both_related()` method returns `Vec<(E::Model, F::Model)>` (both sides non-optional), as a counterpart to the existing `find_also_related()` which returns `Vec<(E::Model, Option<F::Model>)>`. Use this when you know the relation is always populated and want to avoid the `Option` unwrap:
```rust
let results: Vec<(Order, LineItem)> = Order::find()
.find_both_related(LineItem)
.all(db)
.await?;
```
**`set_ne` / `set_ne_and` aliases on `ActiveValue`** (#3040)
Shorter aliases for `set_if_not_equals` and `set_if_not_equals_and`. The long-form names are kept as compatibility aliases:
```rust
// Before
active_model.name.set_if_not_equals("Alice");
// After
active_model.name.set_ne("Alice");
```
**`map_sqlx_*_pool_opts` on `ConnectOptions`** (#2770)
Three new methods to customise the underlying `sqlx::pool::PoolOptions` before the connection pool is created — one per driver:
```rust
ConnectOptions::new(DATABASE_URL)
.map_sqlx_postgres_pool_opts(|opts| opts.max_connections(20).min_connections(5))
.to_owned()
```
**`BTreeMap` / `HashMap` support in `TryGetableFromJson`** (#3009)
Map types can now be used directly as model fields when the column holds a JSON object:
```rust
pub struct Model {
pub id: i32,
pub metadata: HashMap<String, serde_json::Value>,
}
```
**Inherited visibility in derive macros** (#3029)
`DeriveEntityModel`, `DeriveActiveModel`, `DeriveModel`, and related macros now inherit the `pub(crate)` / `pub(super)` / private visibility of the struct they are applied to, instead of always emitting `pub` items.
### Bug Fixes
**Schema sync: drop unique constraint on PostgreSQL** (#2994)
`DROP INDEX` fails on PostgreSQL for unique indexes created via column-level `UNIQUE` because they are backed by a named constraint, not a standalone index. Schema sync now uses `ALTER TABLE … DROP CONSTRAINT` on PostgreSQL and falls back to `DROP INDEX` on other backends.
**Schema sync: tables in non-default schemas now discovered** (#3016)
`sync()` previously ran schema discovery only against `CURRENT_SCHEMA()`. Entities with `#[sea_orm(schema_name = "other")]` were never found, causing every sync to attempt a redundant `CREATE TABLE`. Discovery now collects all schemas referenced by registered entities and queries each one.
**Nested `PartialModel` null detection for optional fields** (#3039)
A nested `Option<PartialModel>` loaded via a left join could incorrectly fail with `Missing value for column 'id'` when the nested model itself contained `Option<T>` fields. The null check now correctly handles arbitrary `Option` nesting depth.
**`use_transaction` per-migration config was ignored** (#3002)
`exec_with_connection` unconditionally wrapped all PostgreSQL migration operations in a transaction, overriding the per-migration `use_transaction` setting. The macro has been removed and each call site now uses the correct connection type.
**Proc macros failed on long type paths with newlines** (#3031)
`DeriveActiveModelEx` and other derive macros used `.replace(' ', "")` to strip whitespace, which missed newlines in formatted type paths longer than ~50 characters. Replaced with `.split_whitespace().collect()`.
**`TIMESTAMPTZ` conversion in the Postgres proxy driver** (#3004)
`from_sqlx_postgres_row_to_proxy_row` now correctly converts `TIMESTAMPTZ` columns, fixing a panic when using the proxy driver with timestamptz fields.
### Dependency Updates
- `arrow` updated to 58 (#3007)
- `strum` updated to 0.28 (#2993)
+67
View File
@@ -0,0 +1,67 @@
## Release Notes: SeaORM 2.0.0-rc.39
*(since 2.0.0-rc.38)*
### Dependency Upgrades
**SeaQuery 1.0, SeaSchema 0.18, and SQLx 0.9** (#3074)
SeaORM now builds on the stable SeaQuery 1.0 release and SQLx 0.9. This is the main payload of rc.39:
- `sea-query` is now `~1.0.0`
- `sea-query-sqlx` is now `0.9.0`
- `sea-schema` and `sea-schema-sync` are now `0.18.0`
- `sqlx` and `sqlx-core` are now `0.9.0`
Runtime and driver feature wiring has been updated for SQLx 0.9's split runtime and TLS feature names. `sea-orm-migration`, `sea-orm-cli`, examples, and `sea-orm-sync` have been kept in sync with the new dependency graph.
Compatibility notes:
- This RC is dependency-breaking relative to rc.38 because it promotes SeaQuery, SeaSchema, and SQLx to their next major/minor release lines.
- `sea-query` is intentionally constrained to `~1.0.0`, allowing 1.0.x patches without automatically accepting 1.1.x.
- No intentional schema-discovery or entity-generation behavior change is expected from the dependency upgrade itself, aside from the frontend import fix listed below.
**MSRV updates**
The async crate now requires Rust 1.94.0. `sea-orm-sync` now requires Rust 1.88.0.
### New Features
**Async closure transaction helpers** (#3074)
`DatabaseConnection` and `DatabaseTransaction` now expose inherent async-closure transaction helpers:
```rust
db.transaction_async(async |txn| {
bakery::Entity::insert(active_model).exec(txn).await?;
Ok(())
})
.await?;
```
The existing `TransactionTrait::transaction` and `TransactionTrait::transaction_with_config` APIs are still available. The new inherent methods provide a forward-compatible path with async closures while preserving the trait API for existing users.
**Optional `db.statement` recording in tracing spans** (#3045)
`ConnectOptions::record_stmt_in_spans(false)` disables recording full SQL text into the `db.statement` tracing field while still emitting database operation spans:
```rust
let mut opt = ConnectOptions::new(DATABASE_URL);
opt.record_stmt_in_spans(false);
```
This is useful for deployments that want query timing and operation visibility without storing statement text in traces. The default remains `true`.
### Bug Fixes
**Use wasm-compatible `Instant` for wasm32** (#3071)
The rusqlite driver now uses a wasm-compatible time source on `wasm32`, avoiding `std::time::Instant` issues in wasm builds.
**Generate correct imports in `frontend` entity output** (#3037)
The code generator now emits the required imports for frontend-format entities using date/time, decimal, UUID, vector, network, JSON, and array column types. This fixes generated frontend entity files that previously referenced those types without importing them.
### Examples
Examples were refreshed for the rc.39 dependency versions. Loco, Seaography, and React Admin examples keep local `sea-orm` / `sea-orm-migration` patches so CI and local checks exercise the workspace crates instead of resolving the last published RC.
+21
View File
@@ -0,0 +1,21 @@
## Release Notes: SeaORM 2.0.0-rc.40
*(since 2.0.0-rc.39)*
### Bug Fixes
**Restore PostgreSQL pgvector binding with SQLx 0.9**
SeaORM now resolves `sea-query-sqlx 0.9.1`, which restores SQLx binder support for PostgreSQL `pgvector` values.
`sea-query-sqlx 0.9.0` accidentally disabled the `pgvector/sqlx` integration and made `Value::Vector` binding panic in the PostgreSQL SQLx binder. This affected SeaORM users inserting or updating `PgVector` values through the SQLx Postgres driver.
SeaORM no longer pins `sea-query-sqlx` to exactly `0.9.0`; it now allows compatible `0.9.x` patch releases.
### Tests
The PostgreSQL pgvector integration test was restored for the current test harness and verified against a `pgvector/pgvector:pg14` database.
### Compatibility Notes
No generated SQL changes are expected from this RC. The release fixes a runtime binding regression for `PgVector` values when using SQLx Postgres.
+210
View File
@@ -0,0 +1,210 @@
## Release Notes: SeaORM 2.0.0-rc.41
*(since 2.0.0-rc.40)*
### New Features
**`SelectFourMany` with `consolidate()`** (#3054)
`SelectFour::consolidate()` returns a `SelectFourMany`; its `all()` (star topology)
rolls the three has-many children up into `Vec`s — `Vec<(E::Model, Vec<F::Model>,
Vec<G::Model>, Vec<H::Model>)>` — mirroring `SelectThreeMany` instead of returning
flat `Option` tuples.
```rust
let rows = parent::Entity::find()
.find_also_related(a::Entity)
.find_also_related(b::Entity)
.find_also(parent::Entity, c::Entity)
.consolidate()
.all(db)
.await?;
```
**Update without returning** (#2965)
`ActiveModelTrait::update_without_returning` (and `UpdateOne` /
`ValidatedUpdateOne::exec_without_returning`) run an UPDATE without a RETURNING
clause, yielding an `UpdateResult` — useful on backends without RETURNING or when
the model isn't needed. It runs `before_save`, skips `after_save`, and returns
`DbErr::RecordNotUpdated` when no row matches.
```rust
let res = active_model.update_without_returning(db).await?;
```
**Explicit prefixes for nested result models** (#2989)
`FromQueryResult` and `DerivePartialModel` accept `#[sea_orm(nested(prefix = "..."))]`,
so a model can hold several nested fields of the same type without column clashes:
```rust
#[sea_orm(nested(prefix = "mgr_"), alias = "manager")]
manager: Worker,
#[sea_orm(nested(prefix = "csh_"), alias = "cashier")]
cashier: Worker,
```
**Migration CLI custom connection entrypoints** (#3035)
`sea-orm-migration` exposes custom connection entrypoints so applications can
customize `ConnectOptions`, load SQLite extensions, or build the connection from
their own config before running migration commands.
```rust
run_cli_with_connection(migrator, |mut opt: ConnectOptions| async move {
opt.sqlx_logging(false); // ...or load extensions, read app config, etc.
Database::connect(opt).await
})
.await;
```
**Prebuilt `sea-orm-cli` binaries via `cargo-binstall`** (#2877)
Releases now publish prebuilt `sea-orm-cli` binaries for Linux (x64/arm64), macOS
(x64/arm64), and Windows (x64), and the crate carries `cargo-binstall` metadata, so
`cargo binstall sea-orm-cli` installs without compiling from source.
### Enhancements
**Stable serde for first-party value wrappers** (#3023)
First-party wrappers now have explicit serde impls instead of relying on derive
shape: `TextUuid` is a JSON string, and the Unix-timestamp wrappers
(`ChronoUnixTimestamp`, `ChronoUnixTimestampMillis`, `TimeUnixTimestamp`,
`TimeUnixTimestampMillis`) are JSON `i64`s matching their stored value.
```rust
let json = serde_json::to_string(&TextUuid::from(uuid))?; // "\"<uuid>\""
serde_json::from_str::<TextUuid>("\"not-a-uuid\"").is_err(); // parse-checked
```
**Streaming behind `stream` cargo feature** (#3075)
Streaming APIs (`QueryStream`, `StreamTrait`, `Select::stream*`) are gated behind
the `stream` feature, on by default. `default-features = false` without `stream`
drops the `ouroboros` dependency.
```toml
# opt out of streaming (and ouroboros) by dropping default features
sea-orm = { version = "2.0.0-rc.41", default-features = false, features = ["macros", "sqlx-postgres", "runtime-tokio-native-tls"] }
```
**Generated migration names** (#2580)
Generated migrations implement `MigrationName` explicitly, keeping names stable
when the file/module layout is customized.
### Bug Fixes
**`ActiveModelBehavior` runs for junction tables** (#3027, #3010)
When establishing a many-to-many relation through the ActiveModel builder, the
junction-table rows now run their `ActiveModelBehavior` hooks (`before_save` /
`after_save` on inserted via-models, `before_delete` / `after_delete` on removed
ones) instead of being inserted/deleted without hooks.
**Generated entities compile when an enum name collides with a generated identifier** (#2880, #2153)
An enum named like a generated item (`Model`, `Entity`, `ActiveModel`, `Column`,
`PrimaryKey`, `Relation`) is now imported aliased instead of emitting a
conflicting `use`:
```rust
use super::sea_orm_active_enums::Model as ModelEnum;
```
**`serde(rename_all)` no longer breaks `ActiveModel::from_json` defaulting** (#2855, #2854)
Regression from #2842: with `#[serde(rename_all = "...")]` (or field-level
`rename`), missing fields errored instead of defaulting to `ActiveValue::NotSet`.
The default-merge is now keyed off each column's `json_key()`, which respects
both rename forms.
```rust
#[serde(rename_all = "camelCase")]
pub struct Model { #[sea_orm(primary_key)] pub id: i32, pub first_name: String }
// `id` omitted → NotSet again (previously errored "missing field")
let am = ActiveModel::from_json(json!({ "firstName": "Max" }))?;
assert_eq!(am.id, ActiveValue::NotSet);
```
**Entity loader diamond relations** (#3030)
The entity loader distinguishes multiple relations to the same target by their
relation definition rather than table reference, fixing diamond graphs where two
fields point to the same entity through different foreign keys:
```rust
#[sea_orm(belongs_to, from = "sender_id", to = "id")]
pub sender: HasOne<user::Entity>,
#[sea_orm(belongs_to, from = "recipient_id", to = "id")]
pub recipient: HasOne<user::Entity>, // both → user, now loaded independently
```
**Schema-sync indexes for non-default PostgreSQL schemas** (#3085, #3084)
On PostgreSQL, indexes from `#[sea_orm(indexed)]` / `#[sea_orm(unique_key)]` on a
`schema_name` entity now target the qualified table (`ON "sys"."app_user"`),
fixing `relation "..." does not exist` and wrong-schema targeting. MySQL/SQLite
keep unqualified targets (their SeaQuery index builders reject a qualified one),
which also removes a latent panic for `#[sea_orm(unique)]` columns there.
**CLI extra attribute parsing** (#3032)
Entity generation handles comma-separated extra attributes and derives with
nested commas:
```shell
--model-extra-attributes 'serde(rename_all = "camelCase"),ts(export)'
```
**PostgreSQL `drop_everything` with dependent custom types** (#3014)
`drop_everything` drops PostgreSQL custom types with `CASCADE`, cleaning up
dependent domains and functions while preserving extension-owned types.
**Generated `delete_by_*` for single-column unique keys** (#3059)
`model_ex` generates `delete_by_*` helpers for one-column unique keys, matching
the existing `find_by_*` behavior for `#[sea_orm(unique)]` and single-column
`unique_key` fields.
```rust
Entity::delete_by_name("alpha").exec(db).await?; // alongside find_by_name
```
**SQLite file URI parameters** (#3072)
Rusqlite connections allow SQLite file URI query parameters (e.g. shared
in-memory databases), leaving validation to SQLite.
```rust
Database::connect("sqlite:file:mydb?mode=memory&cache=shared").await?;
```
**SQLite timestamp with time zone reads** (#2878)
Timestamp-with-time-zone values preserve their stored offset instead of
normalizing through UTC on read.
**Tracing instrumentation no longer records SQL arguments by default** (#3047)
Automatic `tracing::instrument` fields drop SQL arguments; SQL recording stays
controlled by the explicit tracing span setting.
### Compatibility Notes
- Serde shape for first-party wrappers is now explicit: `TextUuid` ↔ JSON string,
Unix-timestamp wrappers ↔ JSON integers.
- SQLite timestamp-with-time-zone reads preserve offsets; PostgreSQL
`drop_everything` is intentionally more destructive for custom-type dependents.
- The entity loader change adds methods to the public loader traits — generated
code updates automatically, but manual trait impls must add them.
- `default-features = false` users of streaming must enable `stream`.
- Tracing spans no longer carry SQL statements/arguments as automatic
`instrument` fields; re-enable via the explicit tracing span setting if needed.
- Nested prefixes are opt-in; existing unprefixed `#[sea_orm(nested)]` fields
still compile. Reusing the same non-empty prefix for the same nested type is a
compile error (the fields would decode from identical aliases).
+96
View File
@@ -0,0 +1,96 @@
## Release Notes: SeaORM 2.0.0-rc.42
*(since 2.0.0-rc.41)*
### New Features
**Typed value arrays via `try_getable_array`** (#3108, #2967)
`DeriveValueType` wrappers backed by a `Vec<_>` now round-trip as native
PostgreSQL arrays: the derive generates a `try_getable_array` implementation, so
a newtype over `Vec<i32>` reads and writes as `INTEGER[]` without a manual
`TryGetable` impl.
```rust
#[derive(Clone, Debug, PartialEq, DeriveValueType)]
pub struct Tags(Vec<String>);
```
**Replace and delete a nested `HasOne`** (#3110, #3060, #3061)
The active has-one type (`ActiveHasOne`) gains a `Delete` variant plus generated
`delete_<field>` / `set_<field>_option` builders. Setting a populated has-one now
*replaces* the existing linked record (deleting or orphaning the old one) instead
of erroring, and `Delete` removes it on save.
```rust
let mut user = user::Entity::load().filter_by_id(1).with(profile::Entity).one(db).await?.unwrap();
user.delete_profile().save(db).await?; // remove the linked profile
```
**`TryFrom<&str>` for active enums** (#3111)
`DeriveActiveEnum` now generates a `TryFrom<&str>` implementation, so a string
value can be parsed straight into the enum by its database string representation.
```rust
let color = Color::try_from("Black")?;
```
### Enhancements
**`ActiveHasOne` / `ActiveHasMany`** (renamed)
The active/write-side companions to `HasOne` / `HasMany` are renamed from
`HasOneModel` / `HasManyModel` to `ActiveHasOne` / `ActiveHasMany`, so the names
read as active-model values rather than loaded models. The read-side `HasOne` /
`HasMany` types are unchanged.
**Documented `SqlErr` and `DbErr::sql_err()`** (#2940)
`DbErr::sql_err()` and the `SqlErr` variants are documented, including how to reach
the raw driver error for backend-specific handling.
```rust
if let Some(SqlErr::UniqueConstraintViolation(_)) = err.sql_err() { /* ... */ }
```
**Schema sync warns on column-type divergence** (#3106)
`SchemaBuilder::sync()` logs a warning when a live column's type diverges from the
entity definition instead of silently ignoring the difference.
### Bug Fixes
**Codegen `ColumnType` coverage** (#3092)
Entity generation emits compiling code for `Year`, `Bit`, `VarBit`, `MacAddr`,
`LTree`, and `Interval` columns, and for `Money` columns carrying precision and
scale — previously these produced non-compiling `ColumnType` expressions.
**Skip generated columns in entity generation** (#3094)
`sea-orm-cli generate entity` skips database-generated columns, which cannot be
inserted or updated, instead of emitting them as ordinary fields.
**`SchemaBuilder::sync()` returns a `Send` future** (#3100)
Regression fix: `sync()` no longer returns a non-`Send` future, so it can be used
across `.await` points on multi-threaded runtimes. Released together with
sea-schema 0.18.1.
**`sea-orm-sync` generation fixes** (#3112)
The `make-sync` transform correctly handles `futures_util` usage in the mock
driver, keeping the blocking `sea-orm-sync` crate in sync with the async source.
### Compatibility Notes
- `HasOneModel` / `HasManyModel` are renamed to `ActiveHasOne` / `ActiveHasMany`.
Update references; the read-side `HasOne` / `HasMany` are unaffected.
- `DbErr`, `UpdateResult`, `DeleteResult`, `ActiveHasOne`, and `ActiveHasMany` are
now `#[non_exhaustive]`; downstream `match`es need a wildcard arm.
- Schema sync and nested-ActiveModel relation mutation are marked unstable
(semver-exempt) while their APIs settle.
- Prebuilt `sea-orm-cli` binaries no longer include the Intel macOS
(`x86_64-apple-darwin`) target.
+77
View File
@@ -0,0 +1,77 @@
## Release Notes: SeaORM 2.0.0-rc.43
*(since 2.0.0-rc.42)*
### New Features
**`BelongsTo` relation type** (#3118, #3133, #3134)
A dedicated `BelongsTo<E>` / `BelongsTo<Option<E>>` type for `belongs_to` relations,
alongside the existing `HasOne`. Cardinality lives in the type parameter, so the
foreign-key nullability is expressed — and checked — at compile time:
- `BelongsTo<E>` — the FK is `NOT NULL`; the relation cannot be detached (there is
no way to set it to "none" on the active side), so orphaning a required parent is
a compile error rather than a runtime constraint violation.
- `BelongsTo<Option<E>>` — the FK is nullable; the relation can be detached, which
nulls the FK on save.
The cardinality is validated against the FK columns when the entity is derived:
`BelongsTo<Entity>` requires every `from` column to be `NOT NULL`, and
`BelongsTo<Option<Entity>>` requires at least one nullable `from` column — a mismatch
is a compile error. Composite foreign keys with mixed nullability detach by nulling
only their nullable columns.
```rust
#[sea_orm(belongs_to, from = "user_id", to = "id")]
pub author: BelongsTo<super::user::Entity>, // required
#[sea_orm(belongs_to, from = "bakery_id", to = "id")]
pub bakery: BelongsTo<Option<super::bakery::Entity>>, // optional
```
The active side is `ActiveBelongsTo<..>`, mirroring `ActiveHasOne` / `ActiveHasMany`.
**`HasOne` still works for `belongs_to` — no migration required** (#3133)
Adopting `BelongsTo` is opt-in. A `belongs_to` field may keep its existing
`HasOne<Entity>` type; it continues to compile and behave as before. Use `BelongsTo`
when you want the compile-time cardinality guarantee; otherwise nothing changes.
### Enhancements
**CLI lists valid options on generation error** (#3131)
`sea-orm-cli generate entity` now prints the valid choices when an invalid option
value is supplied, instead of only reporting that the value was rejected.
### Bug Fixes
**`has_related` with a `Condition::any()` filter** (#3126)
`has_related` wrapped the caller's condition and then added the mandatory FK/join
condition to it. When the caller passed a `Condition::any()` (an `OR` group), the
join condition was folded into that disjunction, so the relation constraint was no
longer guaranteed. The caller's condition is now wrapped in `Condition::all()` first,
yielding `(caller condition) AND (fk join)` regardless of `any()` / `all()`.
**Entity codegen for PostgreSQL enum array columns** (#3120)
Array-of-enum columns were generated as scalar active-enum fields because the type
resolver unwrapped `Array(Enum)` to `Enum`. Array columns now route through the
full type resolver, so `enum[]` columns generate `Vec<Enum>` fields.
### Compatibility Notes
- `belongs_to` relations may now be typed `BelongsTo<Entity>` /
`BelongsTo<Option<Entity>>`. This is opt-in — existing `HasOne`-typed `belongs_to`
fields are unchanged and still supported. `sea-orm-cli` continues to generate the
`HasOne` form.
- The compile-time detach guarantee applies only to `BelongsTo<Entity>` (non-null);
it is a property of the type, so it costs nothing at runtime.
- A `BelongsTo` field's type parameter must match its FK nullability (checked when
the entity is derived). This only affects code that opts into `BelongsTo`.
- The nested-`ActiveModel` relation types remain semver-exempt (unstable): rc.43
drops their `PartialEq<Option<..>>` impls, so compare an empty relation with
`is_unloaded_or_not_found()` / `is_not_found()` / `as_ref()` rather than `== None`
/ `== Some(..)`.
+138
View File
@@ -0,0 +1,138 @@
# SeaORM 2.0.0
SeaORM 2.0 is the first stable release of the 2.x line. It reworks how entities,
relations, and ActiveModels are defined and used, adds an entity-first workflow,
introduces role-based access control, and brings the library onto SeaQuery 1.0 and
SQLx 0.9.
The full, itemized changelog for the 2.0 series (all release candidates included)
is in [CHANGELOG.md](../CHANGELOG.md#200---2026-07-19).
## Highlights
### New entity format
Relations are now declared directly on the `Model` struct with `#[sea_orm::model]`,
replacing the separate `Relation` enum and `Related` impls.
```rust
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "user")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
#[sea_orm(has_one)]
pub profile: HasOne<super::profile::Entity>,
#[sea_orm(has_many)]
pub posts: HasMany<super::post::Entity>,
}
```
See the [new entity format walk-through](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/).
### `BelongsTo` relation type with compile-time cardinality
A `belongs_to` relation can be typed `BelongsTo<Entity>` (required) or
`BelongsTo<Option<Entity>>` (optional), encoding the foreign-key cardinality in the
type and paired with the write-side `ActiveBelongsTo`. The macro validates the type
against the nullability of the `from` columns at compile time. `BelongsTo` is the
recommended type for `belongs_to`; the legacy `HasOne<Entity>` field type remains
supported for backward compatibility. (https://github.com/SeaQL/sea-orm/pull/3118)
### Strongly-typed columns
Filter with the typed `COLUMN` constant for compile-time type safety, alongside the
existing `Column` enum.
```rust
user::Entity::find().filter(user::COLUMN.name.contains("Bob"))
```
See [strongly-typed columns](https://www.sea-ql.org/blog/2025-11-11-sea-orm-2.0/).
### Nested ActiveModel
Build and persist an entity together with its related rows in one expression, and
push has-many children onto a loaded model.
```rust
let bob = user::ActiveModel::builder()
.set_name("Bob")
.set_email("bob@sea-ql.org")
.set_profile(profile::ActiveModel::builder().set_picture("Tennis"))
.insert(db)
.await?;
```
See [nested ActiveModel](https://www.sea-ql.org/blog/2025-11-25-sea-orm-2.0/).
### Entity Loader
Load an entity together with its relations, including nested relations, in a single
call.
```rust
let user = user::Entity::load()
.filter_by_id(12)
.with(profile::Entity)
.with((post::Entity, comment::Entity))
.one(db)
.await?;
```
### Entity-first workflow
Create tables directly from entity definitions via the schema registry, without
writing a migration first.
```rust
db.get_schema_registry("my_crate::*").sync(db).await?;
```
See the [entity-first workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/).
### Role-Based Access Control
A table-scoped, hierarchical RBAC engine with a query auditor and a
`RestrictedConnection` that implements `ConnectionTrait` and enforces permissions on
all Entity operations (including complex joins, insert-select, and CTE queries).
(https://github.com/SeaQL/sea-orm/pull/2683)
### Overhauled `insert_many`
`insert_many` no longer shares a helper struct with single insert. Panic-prone APIs
were removed, empty input returns `None` / `vec![]` on exec, and the new `InsertMany`
helper exposes `last_insert_id: Option<Value>`. (https://github.com/SeaQL/sea-orm/pull/2628)
### Synchronous SeaORM
The `sea-orm-sync` crate provides a synchronous SeaORM backed by `rusqlite`, mirroring
the async API with async/await stripped away.
## Upgrading from 1.x
Follow the [1.0 to 2.0 migration guide](https://www.sea-ql.org/blog/2026-01-12-sea-orm-2.0/)
and the [2.0 walk-through](https://www.sea-ql.org/blog/2025-12-05-sea-orm-2.0/).
Notable breaking changes to be aware of:
- Expression methods like `.eq()`, `.like()`, `.contains()` now require
`use sea_orm::ExprTrait;` in scope. Also read
[SeaQuery's breaking changes](https://github.com/SeaQL/sea-query/blob/master/CHANGELOG.md#breaking-changes).
- `execute` / `query_one` / `query_all` / `stream` now take a SeaQuery statement; the
raw-SQL variants are `execute_raw` / `query_one_raw` / `query_all_raw` / `stream_raw`.
- PostgreSQL auto-increment columns now use `GENERATED BY DEFAULT AS IDENTITY` instead
of `serial`; opt back in with `option-postgres-use-serial` if needed.
- SQLite maps both `Integer` and `BigInteger` to `integer`.
- `DeriveValueType` now also derives `NotU8`, `IntoActiveValue`, and `TryFromU64`;
remove any manual implementations to avoid conflicts.
- Removed the `runtime-actix` feature alias (use `runtime-tokio`); removed
`DeriveCustomColumn` and `default_as_str`.
## Dependencies
- SeaQuery 1.0
- SQLx 0.9
- sea-schema 0.18