Skip to content

0.11.0

Compare
Choose a tag to compare
@tyt2y3 tyt2y3 released this 07 Feb 10:31

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::fmt module #1325
  • Support Vector of enum for Postgres #1210
  • Support ActiveEnum field as primary key #1414
  • Casting columns as a different data type on select, insert and update #1304
  • Methods of ActiveModelBehavior receive db connection as a parameter #1145, #1328
  • Added execute_unprepared method to DatabaseConnection and DatabaseTransaction #1327
  • Added Select::into_tuple to 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() and MockDatabase::append_query_errors() take any types implemented IntoIterator trait #1367
  • find_by_id and delete_by_id take any Into primary key value #1362
  • QuerySelect::offset and QuerySelect::limit takes in Into<Option<u64>> where None would reset them #1410
  • Added DatabaseConnection::close #1236
  • Added is_null getter for ColumnDef #1381
  • Added ActiveValue::reset to convert Unchanged into Set #1177
  • Added QueryTrait::apply_if to optionally apply a filter #1415
  • Added the sea-orm-internal feature flag to expose some SQLx types
    • Added DatabaseConnection::get_*_connection_pool() for accessing the inner SQLx connection pool #1297
    • Re-exporting SQLx errors #1434

Upgrades

  • Upgrade axum to 0.6.1 #1285
  • Upgrade sea-query to 0.28 #1366
  • Upgrade sea-query-binder to 0.3 #1366
  • Upgrade sea-schema to 0.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 qualifying IdenStatic::as_str) #1280
  • Prevent returning connections to pool with a positive transaction depth #1283
  • Postgres insert many will throw RecordNotInserted error if non of them are being inserted #1021
    • Fixes inserting active models by insert_many with on_conflict and do_nothing panics if no rows are inserted on Postgres #899
  • Don't call last_insert_id if 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 RecordNotInserted and RecordNotUpdated to DbErr
  • Added ConnectionTrait::execute_unprepared method #1327
  • As part of #1311, the required method of TryGetable changed:
// 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 ActiveModelBehaviour trait becomes async trait #1328.
    If you overridden the default ActiveModelBehaviour implementation:
#[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 variant DbErr::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::ColumnType was replaced by sea_query::ColumnType #1395
    • Method ColumnType::def was moved to ColumnTypeTrait
    • ColumnType::Binary becomes a tuple variant which takes in additional option sea_query::BlobSize
    • ColumnType::Custom takes a sea_query::DynIden instead of String and thus a new method custom is added (note the lowercase)
// 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

  • Fixed a small typo #1391
  • axum example should use tokio runtime #1428

New Contributors

Full Changelog: 0.10.0...0.11.0