sea-orm-cli@2.0.4
Upgrade arrow to 60 (sea-orm-arrow 2.0.0-rc.5)
2.0.4
(since 2.0.3)
-
Add
select_exceptto select all columns except the given ones https://github.com/SeaQL/sea-orm/pull/3211select_exceptprovides the inverse ofselect_only/column——selecting all columns except the specified ones.These methods replace the current selection, so the last one called takes effect.
#[derive(DerivePartialModel)] #[sea_orm(entity = "post::Entity")] struct PostPreview { id: i32, title: String, } let posts = post::Entity::find() .select_except([post::Column::Body]) .into_model::<PostPreview>() .all(db) .await?;
-
Fix chained
left_join_linkedusing the wrong alias for links with multiple relations https://github.com/SeaQL/sea-orm/pull/3199When
left_join_linkedwas called more than once, later joins in a multi-relation link could refer to aliases belonging to the first call. The query remained valid but could return incorrect rows.cake::Entity::find() .left_join_linked(CakeToFilling) .left_join_linked(CakeToFillingVendor)
-- before LEFT JOIN `filling` AS `r3` ON `r0`.`filling_id` = `r3`.`id` -- after LEFT JOIN `filling` AS `r3` ON `r2`.`filling_id` = `r3`.`id`
-
Respect
condition_typein linked joins https://github.com/SeaQL/sea-orm/pull/3203left_join_linkedandfind_linkedalways combined the relation condition andon_conditionwithAND, even whenConditionType::Anywas specified.They now follow
condition_type, matching regularjoin().cake::Relation::Fruit .def() .condition_type(ConditionType::Any) .on_condition(|_left, right| { Expr::col((right, fruit::Column::Name)) .like("%tropical%") .into_condition() })
-- before LEFT JOIN `fruit` AS `r0` ON `cake`.`id` = `r0`.`cake_id` AND `r0`.`name` LIKE '%tropical%' -- after LEFT JOIN `fruit` AS `r0` ON `cake`.`id` = `r0`.`cake_id` OR `r0`.`name` LIKE '%tropical%'
-
Fix
save_asnot being applied to array values ineq_any/ne_allhttps://github.com/SeaQL/sea-orm/pull/3208#[sea_orm(column_type = r#"custom("citext")"#, save_as = "citext")] pub email: String, Entity::find().filter(Column::Email.eq_any(["a@x.com".to_owned(), "B@x.com".to_owned()]))
-- before: text[], case-sensitive WHERE "user"."email" = ANY(ARRAY ['a@x.com','B@x.com']) -- after WHERE "user"."email" = ANY(CAST(ARRAY ['a@x.com','B@x.com'] AS citext[]))
-
Fix schema sync failing to drop a stale unique index on MySQL https://github.com/SeaQL/sea-orm/pull/3202
Removing
#[sea_orm(unique)]from a column could make the next schema sync fail with MySQL error 1064.
-
Upgrade
arrowto 60 (sea-orm-arrow2.0.0-rc.5)with-arrownow builds against arrow 60. Arrow types passed to SeaORM, such as aRecordBatchforfrom_arrow, must come from arrow 60 too, so crates likeparquetneed the matching version.arrow = "60" parquet = "60"
sea-orm-cli@2.0.3
update examples
2.0.3
(since 2.0.2)
Selecting two models panicked when a column needed a cast on select. A combined select derives each A_ / B_ prefixed alias from the selected expression, and a cast is neither a plain column nor an enum cast, so that derivation gave up. Columns now carry their own alias into the combined select and the prefix is applied to it https://github.com/SeaQL/sea-orm/pull/3194
Entity::find().select_also(other::Entity).build(DbBackend::Postgres)
// before: panicked with "cannot apply alias for expr other than Column or AsEnum"
-- after
SELECT "hello"."id" AS "A_id", CAST("hello"."two" AS integer) AS "A_two", ...
Generated code referred to bindings by plain name, so a field that happened to share a name with one of them shadowed it and the expansion failed to compile. The generated bindings are now hygienic https://github.com/SeaQL/sea-orm/pull/3185
// did not compile before: `row` and `pre` collided with the generated bindings
#[derive(FromQueryResult)]
struct QueryResultProjection {
row: String,
pre: String,
}
The generated TryFrom<&str> impl wrote its error type as Self::Error, which an Error variant on the enum shadowed. The impl now names sea_orm::DbErr outright https://github.com/SeaQL/sea-orm/pull/3185
#[derive(Debug, EnumIter, DeriveActiveEnum, Eq, PartialEq)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "error_variant")]
enum ErrorVariantEnum {
#[sea_orm(string_value = "error")]
Error, // no longer breaks the generated `TryFrom<&str>`
}
Eq is deliberately not inherited from the model, because a nested relation may hold non-Eq fields — but the filter also discarded an Eq asked for explicitly. An explicit derive is now kept, and the clippy::derive_partial_eq_without_eq warning that the missing Eq triggered is silenced https://github.com/SeaQL/sea-orm/pull/3193
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "user", model_ex_attrs(derive(Eq)))]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
} // ModelEx now derives Eq
A unique index with a WHERE predicate was generated as an unconditional unique column, claiming a constraint the database does not enforce. Partial indexes are now skipped, since codegen cannot express the predicate https://github.com/SeaQL/sea-orm/pull/3196
CREATE UNIQUE INDEX login_human_login_id_key
ON login (human_login_id)
WHERE human_login_id IS NOT NULL; -- no longer emits #[sea_orm(unique)]
The shorthand form has no authority component, so it yields no URL path segments and the CLI reported it as having no database name. The whole path is now read as the database name https://github.com/SeaQL/sea-orm/pull/3197
sea-orm-cli generate entity -u postgres:my_db -o src/entities
-
The alias fix changes emitted SQL for ordinary single-model queries too: a column with a
select_ascast is now followed byAS "<column>". Results are unchanged, but tests asserting on generated SQL strings will need updating.-- Entity::find(), before SELECT "hello"."id", CAST("hello"."two" AS integer), "hello"."three3" FROM "hello" -- after SELECT "hello"."id", CAST("hello"."two" AS integer) AS "two", "hello"."three3" FROM "hello"
-
No public API was added, removed, or changed in
sea-orm,sea-orm-migration,sea-orm-codegen,sea-orm-macrosorsea-orm-cli.
sea-orm-cli@2.0.2
Add changelog for 2.0.2
2.0.2
- Add
require_oneto fetch exactly one row, erroring if none: a non-optional counterpart toone()that returns the item directly and yieldsDbErr::RecordNotFoundwhen no row matches, so call sites can use?instead of unwrapping anOption. Available onSelector/SelectorRawand theSelect,SelectTwo, andSelectTwoRequiredwrappers https://github.com/SeaQL/sea-orm/pull/3164 - Add
date_time_default_nowschema helper — a column defaulting toExpr::current_timestamp()https://github.com/SeaQL/sea-orm/pull/3159 - Add
timestamp_default_nowandtimestamp_with_time_zone_default_nowschema helpers, mirroringdate_time_default_nowfor the timestamp family https://github.com/SeaQL/sea-orm/pull/3165
- CLI: deduplicate grouped vs individual imports when regenerating entities with
--preserve-user-modifications, so a user-groupeduse foo::{A, B}is recognised as equivalent to the freshly generateduse foo::A; use foo::B;and no longer emitted twice https://github.com/SeaQL/sea-orm/pull/3163
sea-orm-cli@2.0.1
Tag seaography example sea-orm version for bump.sh; tolerate taplo padding
2.0.1
- Add
set_pagetoPaginatorto set the current page https://github.com/SeaQL/sea-orm/pull/2963 - Add
as_option/into_optiontoActiveValue<Option<V>>, flattening the outer active-value state and the inner option https://github.com/SeaQL/sea-orm/pull/3155 - Add
set_unsetand friends toActiveValue: set the value only when currentlyNotSethttps://github.com/SeaQL/sea-orm/pull/3083 - Add
is_set_and/is_unchanged_andtoActiveValuehttps://github.com/SeaQL/sea-orm/pull/3125 - Add
ConnectOptions::test_before_acquire_if_idle_for(Duration)— ping a pooled connection before it is handed out only once it has been idle for at least the given duration, instead of on every acquire; setting it disablestest_before_acquire. Alsomap_sqlx_postgres_before_acquire/map_sqlx_mysql_before_acquire/map_sqlx_sqlite_before_acquireto install a per-backend SQLxbefore_acquirecallback (composes with the idle-ping shorthand: idle-ping first, then the callback), plus the corresponding getters https://github.com/SeaQL/sea-orm/pull/3143 - Add
MigratorTrait::get_pending_migrations_read_only/get_applied_migrations_read_only/get_migration_with_status_read_only(and thewith-selfequivalents) — query migration status without runningCREATE TABLE, so a database user without DDL privileges can check pending migrations; if the migration table does not exist, all migrations are reported as pending https://github.com/SeaQL/sea-orm/pull/3144
-
Require
TransactionTrait::Transactionto be a fixed point, fixing nested-transaction recursion (E0275/future_not_send) in#[sea_orm::model]generated save methods https://github.com/SeaQL/sea-orm/pull/3153Compatibility note: if you implement
TransactionTraityourself,Selfmust beSync, and yourTransactiontype must beSendand its own transaction type (Transaction::Transaction = Transaction). Implementations delegating toDatabaseConnection/DatabaseTransaction, and virtually all#[async_trait]implementations, already satisfy this. Callers are unaffected.
- Loco examples upgraded to
loco-rs1.0 (which runs on SeaORM 2.0 stable) https://github.com/SeaQL/sea-orm/pull/3152
sea-orm-cli@2.0.0
Reformat example manifests with taplo after 2.0.0 bump
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.
Relations are now declared directly on the Model struct with #[sea_orm::model], replacing the separate Relation enum and Related impls.
#[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.
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)
Filter with the typed COLUMN constant for compile-time type safety, alongside the existing Column enum.
user::Entity::find().filter(user::COLUMN.name.contains("Bob"))
Build and persist an entity together with its related rows in one expression, and push has-many children onto a loaded model.
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.
Load an entity together with its relations, including nested relations, in a single call.
let user = user::Entity::load()
.filter_by_id(12)
.with(profile::Entity)
.with((post::Entity, comment::Entity))
.one(db)
.await?;
Create tables directly from entity definitions via the schema registry, without writing a migration first.
db.get_schema_registry("my_crate::*").sync(db).await?;
See the entity-first workflow.
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)
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)
The sea-orm-sync crate provides a synchronous SeaORM backed by rusqlite, mirroring the async API with async/await stripped away.
Follow the 1.0 to 2.0 migration guide and the 2.0 walk-through.
Notable breaking changes to be aware of:
- Expression methods like
.eq(),.like(),.contains()now requireuse sea_orm::ExprTrait;in scope. Also read SeaQuery's breaking changes. execute/query_one/query_all/streamnow take a SeaQuery statement; the raw-SQL variants areexecute_raw/query_one_raw/query_all_raw/stream_raw.- PostgreSQL auto-increment columns now use
GENERATED BY DEFAULT AS IDENTITYinstead ofserial; opt back in withoption-postgres-use-serialif needed. - SQLite maps both
IntegerandBigIntegertointeger. DeriveValueTypenow also derivesNotU8,IntoActiveValue, andTryFromU64; remove any manual implementations to avoid conflicts.- Removed the
runtime-actixfeature alias (useruntime-tokio); removedDeriveCustomColumnanddefault_as_str.
- SeaQuery 1.0
- SQLx 0.9
- sea-schema 0.18