https://www.sea-ql.org/blog/2023-02-08-whats-new-in-seaorm-0.11.0/
New Features
SeaORM Core
- Simple data loader #1238, #1443
- Transactions Isolation level and Access mode #1230
- Support various UUID formats that are available in
uuid::fmtmodule #1325 - Support Vector of enum for Postgres #1210
- Support
ActiveEnumfield as primary key #1414 - Casting columns as a different data type on select, insert and update #1304
- Methods of
ActiveModelBehaviorreceive db connection as a parameter #1145, #1328 - Added
execute_unpreparedmethod toDatabaseConnectionandDatabaseTransaction#1327 - Added
Select::into_tupleto select rows as tuples (instead of defining a custom Model) #1311
SeaORM CLI
- Generate
#[serde(skip_deserializing)]for primary key columns #846, #1186, #1318 - Generate
#[serde(skip)]for hidden columns #1171, #1320 - Generate entity with extra derives and attributes for model struct #1124, #1321
SeaORM Migration
- Migrations are now performed inside a transaction for Postgres #1379
Enhancements
- Refactor schema module to expose functions for database alteration #1256
- Generate compact entity with
#[sea_orm(column_type = "JsonBinary")]macro attribute #1346 MockDatabase::append_exec_results(),MockDatabase::append_query_results(),MockDatabase::append_exec_errors()andMockDatabase::append_query_errors()take any types implementedIntoIteratortrait #1367find_by_idanddelete_by_idtake anyIntoprimary key value #1362QuerySelect::offsetandQuerySelect::limittakes inInto<Option<u64>>whereNonewould reset them #1410- Added
DatabaseConnection::close#1236 - Added
is_nullgetter forColumnDef#1381 - Added
ActiveValue::resetto convertUnchangedintoSet#1177 - Added
QueryTrait::apply_ifto optionally apply a filter #1415 - Added the
sea-orm-internalfeature flag to expose some SQLx types
Upgrades
- Upgrade
axumto0.6.1#1285 - Upgrade
sea-queryto0.28#1366 - Upgrade
sea-query-binderto0.3#1366 - Upgrade
sea-schemato0.11#1366
House Keeping
- Fixed all clippy warnings as of
1.67.0#1426 - Removed dependency where not needed #1213
- Disabled default features and enabled only the needed ones #1300
- Cleanup panic and unwrap #1231
- Cleanup the use of
vec!macro #1367
Bug Fixes
- [sea-orm-cli] Propagate error on the spawned child processes #1402
- Fixes sea-orm-cli errors exit with error code 0 #1342
- Fixes
DeriveColumn(by qualifyingIdenStatic::as_str) #1280 - Prevent returning connections to pool with a positive transaction depth #1283
- Postgres insert many will throw
RecordNotInsertederror if non of them are being inserted #1021- Fixes inserting active models by
insert_manywithon_conflictanddo_nothingpanics if no rows are inserted on Postgres #899
- Fixes inserting active models by
- Don't call
last_insert_idif not needed #1403- Fixes hitting 'negative last_insert_rowid' panic with Sqlite #1357
- Noop when update without providing any values #1384
- Fixes Syntax Error when saving active model that sets nothing #1376
Breaking changes
- [sea-orm-cli] Enable --universal-time by default #1420
- Added
RecordNotInsertedandRecordNotUpdatedtoDbErr - Added
ConnectionTrait::execute_unpreparedmethod #1327 - As part of #1311, the required method of
TryGetablechanged:
// then
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError>;
// now; ColIdx can be `&str` or `usize`
fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError>;So if you implemented it yourself:
impl TryGetable for XXX {
- fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
+ fn try_get_by<I: sea_orm::ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {
- let value: YYY = res.try_get(pre, col).map_err(TryGetError::DbErr)?;
+ let value: YYY = res.try_get_by(idx).map_err(TryGetError::DbErr)?;
..
}
}- The
ActiveModelBehaviourtrait becomes async trait #1328.
If you overridden the defaultActiveModelBehaviourimplementation:
#[async_trait::async_trait]
impl ActiveModelBehavior for ActiveModel {
async fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>
where
C: ConnectionTrait,
{
// ...
}
// ...
}DbErr::RecordNotFound("None of the database rows are affected")is moved to a dedicated error variantDbErr::RecordNotUpdated#1425
let res = Update::one(cake::ActiveModel {
name: Set("Cheese Cake".to_owned()),
..model.into_active_model()
})
.exec(&db)
.await;
// then
assert_eq!(
res,
Err(DbErr::RecordNotFound(
"None of the database rows are affected".to_owned()
))
);
// now
assert_eq!(res, Err(DbErr::RecordNotUpdated));sea_orm::ColumnTypewas replaced bysea_query::ColumnType#1395- Method
ColumnType::defwas moved toColumnTypeTrait ColumnType::Binarybecomes a tuple variant which takes in additional optionsea_query::BlobSizeColumnType::Customtakes asea_query::DynIdeninstead ofStringand thus a new methodcustomis added (note the lowercase)
- Method
// Compact Entity
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "fruit")]
pub struct Model {
- #[sea_orm(column_type = r#"Custom("citext".to_owned())"#)]
+ #[sea_orm(column_type = r#"custom("citext")"#)]
pub column: String,
}// Expanded Entity
impl ColumnTrait for Column {
type EntityName = Entity;
fn def(&self) -> ColumnDef {
match self {
- Self::Column => ColumnType::Custom("citext".to_owned()).def(),
+ Self::Column => ColumnType::custom("citext").def(),
}
}
}Miscellaneous
New Contributors
- @goto-eof made their first contribution in #1234
- @tdejager made their first contribution in #1240
- @limjiayi made their first contribution in #1260
- @hut8 made their first contribution in #1302
- @as-cii made their first contribution in #1283
- @karatakis made their first contribution in #1238
- @LeoniePhiline made their first contribution in #1391
- @daniel-samson made their first contribution in #1405
- @Diwakar-Gupta made their first contribution in #1402
- @cemremengu made their first contribution in #1428
- @ippsav made their first contribution in #1430
Full Changelog: 0.10.0...0.11.0