sea-orm

🐚 An async & dynamic ORM for Rust

APACHE-2.0 License

Downloads
13.1M
Stars
6.3K
Committers
202

Bot releases are hidden (Show)

sea-orm - 0.12.1

Published by tyt2y3 about 1 year ago

New Features

#[async_trait::async_trait]
impl MigratorTrait for Migrator {
    // Override the name of migration table
    fn migration_table_name() -> sea_orm::DynIden {
        Alias::new("override_migration_table_name").into_iden()
    }
    ...
}
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "cake")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub name: String,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    // By default, it's
    // `JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'`
    #[sea_orm(
        has_many = "super::fruit::Entity",
        on_condition = r#"super::fruit::Column::Name.like("%tropical%")"#
    )]
    TropicalFruit,
    // Or specify `condition_type = "any"` to override it,
    // `JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` OR `fruit`.`name` LIKE '%tropical%'`
    #[sea_orm(
        has_many = "super::fruit::Entity",
        on_condition = r#"super::fruit::Column::Name.like("%tropical%")"#
        condition_type = "any",
    )]
    OrTropicalFruit,
}
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "primary_key_of_12")]
pub struct Model {
    #[sea_orm(primary_key, auto_increment = false)]
    pub id_1: String,
    ...
    #[sea_orm(primary_key, auto_increment = false)]
    pub id_12: bool,
}
#[derive(DerivePartialModel, FromQueryResult)]
#[sea_orm(entity = "Cake")]
struct PartialCake {
    name: String,
    #[sea_orm(
        from_expr = r#"SimpleExpr::FunctionCall(Func::upper(Expr::col((Cake, cake::Column::Name))))"#
    )]
    name_upper: String,
}

assert_eq!(
    cake::Entity::find()
        .into_partial_model::<PartialCake>()
        .into_statement(DbBackend::Sqlite)
        .to_string(),
    r#"SELECT "cake"."name", UPPER("cake"."name") AS "name_upper" FROM "cake""#
);
assert!(matches!(
    cake.into_active_model().insert(db).await
        .expect_err("Insert a row with duplicated primary key")
        .sql_err(),
    Some(SqlErr::UniqueConstraintViolation(_))
));

assert!(matches!(
    fk_cake.insert(db).await
        .expect_err("Insert a row with invalid foreign key")
        .sql_err(),
    Some(SqlErr::ForeignKeyConstraintViolation(_))
));
fn find_with_related<R>(self, r: R) -> SelectTwoMany<E, R>
    where R: EntityTrait, E: Related<R>;
fn find_with_linked<L, T>(self, l: L) -> SelectTwoMany<E, T>
    where L: Linked<FromEntity = E, ToEntity = T>, T: EntityTrait;

// boths yields `Vec<(E::Model, Vec<F::Model>)>`
  • Added DeriveValueType derive macro for custom wrapper types, implementations of the required traits will be provided, you can customize the column_type and array_type if needed https://github.com/SeaQL/sea-orm/pull/1720
#[derive(DeriveValueType)]
#[sea_orm(array_type = "Int")]
pub struct Integer(i32);

#[derive(DeriveValueType)]
#[sea_orm(column_type = "Boolean", array_type = "Bool")]
pub struct Boolbean(pub String);

#[derive(DeriveValueType)]
pub struct StringVec(pub Vec<String>);
#[derive(DeriveDisplay)]
enum DisplayTea {
    EverydayTea,
    #[sea_orm(display_value = "Breakfast Tea")]
    BreakfastTea,
}
assert_eq!(format!("{}", DisplayTea::EverydayTea), "EverydayTea");
assert_eq!(format!("{}", DisplayTea::BreakfastTea), "Breakfast Tea");
let models: Vec<Model> = Entity::update_many()
    .col_expr(Column::Values, Expr::expr(..))
    .exec_with_returning(db)
    .await?;
#[derive(DeriveEntityModel)]
#[sea_orm(table_name = "hello")]
pub struct Model {
    #[sea_orm(default_expr = "Expr::current_timestamp()")]
    pub timestamp: DateTimeUtc,
}

assert_eq!(
    Column::Timestamp.def(),
    ColumnType::TimestampWithTimeZone.def()
        .default(Expr::current_timestamp())
);
enum DbErr {
    ConnectionAcquire(ConnAcquireErr),
    ..
}

enum ConnAcquireErr {
    Timeout,
    ConnectionClosed,
}

Seaography

Added Seaography integration https://github.com/SeaQL/sea-orm/pull/1599

  • Added DeriveEntityRelated macro which will implement seaography::RelationBuilder for RelatedEntity enumeration when the seaography feature is enabled

  • Added generation of seaography related information to sea-orm-codegen.

    The RelatedEntity enum is added in entities files by sea-orm-cli when flag seaography is set:

/// SeaORM Entity
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
pub enum RelatedEntity {
    #[sea_orm(entity = "super::bakery::Entity")]
    Bakery,
    #[sea_orm(entity = "super::cake_baker::Entity")]
    CakeBaker,
    #[sea_orm(entity = "super::cake::Entity")]
    Cake,
}

Enhancements

let migrations = Migrator::get_pending_migrations(db).await?;
assert_eq!(migrations.len(), 5);

let migration = migrations.get(0).unwrap();
assert_eq!(migration.name(), "m20220118_000002_create_fruit_table");
assert_eq!(migration.status(), MigrationStatus::Pending);
  • The postgres-array feature will be enabled when sqlx-postgres backend is selected https://github.com/SeaQL/sea-orm/pull/1565
  • Replace String parameters in API with Into<String> https://github.com/SeaQL/sea-orm/pull/1439
    • Implements IntoMockRow for any BTreeMap that is indexed by string impl IntoMockRow for BTreeMap<T, Value> where T: Into<String>
    • Converts any string value into ConnectOptions - impl From<T> for ConnectOptions where T: Into<String>
    • Changed the parameter of method ConnectOptions::new(T) where T: Into<String> to takes any string SQL
    • Changed the parameter of method Statement::from_string(DbBackend, T) where T: Into<String> to takes any string SQL
    • Changed the parameter of method Statement::from_sql_and_values(DbBackend, T, I) where I: IntoIterator<Item = Value>, T: Into<String> to takes any string SQL
    • Changed the parameter of method Transaction::from_sql_and_values(DbBackend, T, I) where I: IntoIterator<Item = Value>, T: Into<String> to takes any string SQL
    • Changed the parameter of method ConnectOptions::set_schema_search_path(T) where T: Into<String> to takes any string
    • Changed the parameter of method ColumnTrait::like(), ColumnTrait::not_like(), ColumnTrait::starts_with(), ColumnTrait::ends_with() and ColumnTrait::contains() to takes any string
  • Added sea_query::{DynIden, RcOrArc, SeaRc} to entity prelude https://github.com/SeaQL/sea-orm/pull/1661
  • Added expr, exprs and expr_as methods to QuerySelect trait https://github.com/SeaQL/sea-orm/pull/1702
  • Added DatabaseConnection::ping https://github.com/SeaQL/sea-orm/pull/1627
|db: DatabaseConnection| {
    assert!(db.ping().await.is_ok());
    db.clone().close().await;
    assert!(matches!(db.ping().await, Err(DbErr::ConnectionAcquire)));
}
// now, you can do:
let res = Bakery::insert_many(std::iter::empty())
    .on_empty_do_nothing()
    .exec(db)
    .await;

assert!(matches!(res, Ok(TryInsertResult::Empty)));
let on = OnConflict::column(Column::Id).do_nothing().to_owned();

// Existing behaviour
let res = Entity::insert_many([..]).on_conflict(on).exec(db).await;
assert!(matches!(res, Err(DbErr::RecordNotInserted)));

// New API; now you can:
let res =
Entity::insert_many([..]).on_conflict(on).do_nothing().exec(db).await;
assert!(matches!(res, Ok(TryInsertResult::Conflicted)));

Bug Fixes

#[derive(DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "String(None)")]
pub enum StringValue {
    #[sea_orm(string_value = "")]
    Member1,
    #[sea_orm(string_value = "$$")]
    Member2,
}
// will now produce the following enum:
pub enum StringValueVariant {
    __Empty,
    _0x240x24,
}

Breaking changes

// then:

#[derive(Iden)]
#[iden = "category"]
pub struct CategoryEnum;

#[derive(Iden)]
pub enum Tea {
    Table,
    #[iden = "EverydayTea"]
    EverydayTea,
}

// now:

#[derive(DeriveIden)]
#[sea_orm(iden = "category")]
pub struct CategoryEnum;

#[derive(DeriveIden)]
pub enum Tea {
    Table,
    #[sea_orm(iden = "EverydayTea")]
    EverydayTea,
}

Upgrades

House keeping

New Contributors

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.11.1...0.12.1

sea-orm - 0.11.3

Published by billy1624 over 1 year ago

Enhancements

#[derive(FromQueryResult)]
struct GenericTest<T: TryGetable> {
    foo: i32,
    bar: T,
}
trait MyTrait {
    type Item: TryGetable;
}

#[derive(FromQueryResult)]
struct TraitAssociateTypeTest<T>
where
    T: MyTrait,
{
    foo: T::Item,
}

Bug Fixes

sea-orm - 0.11.2

Published by billy1624 over 1 year ago

Enhancements

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.11.1...0.11.2

sea-orm - 0.11.1

Published by billy1624 over 1 year ago

Bug Fixes

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "binary")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    #[sea_orm(column_type = "Binary(BlobSize::Blob(None))")]
    pub binary: Vec<u8>,
    #[sea_orm(column_type = "Binary(BlobSize::Blob(Some(10)))")]
    pub binary_10: Vec<u8>,
    #[sea_orm(column_type = "Binary(BlobSize::Tiny)")]
    pub binary_tiny: Vec<u8>,
    #[sea_orm(column_type = "Binary(BlobSize::Medium)")]
    pub binary_medium: Vec<u8>,
    #[sea_orm(column_type = "Binary(BlobSize::Long)")]
    pub binary_long: Vec<u8>,
    #[sea_orm(column_type = "VarBinary(10)")]
    pub var_binary: Vec<u8>,
}
  • The CLI command sea-orm-cli generate entity -u '<DB-URL>' --expanded-format will now generate the following code for each Binary or VarBinary columns in expanded format https://github.com/SeaQL/sea-orm/pull/1529
impl ColumnTrait for Column {
    type EntityName = Entity;
    fn def(&self) -> ColumnDef {
        match self {
            Self::Id => ColumnType::Integer.def(),
            Self::Binary => ColumnType::Binary(sea_orm::sea_query::BlobSize::Blob(None)).def(),
            Self::Binary10 => {
                ColumnType::Binary(sea_orm::sea_query::BlobSize::Blob(Some(10u32))).def()
            }
            Self::BinaryTiny => ColumnType::Binary(sea_orm::sea_query::BlobSize::Tiny).def(),
            Self::BinaryMedium => ColumnType::Binary(sea_orm::sea_query::BlobSize::Medium).def(),
            Self::BinaryLong => ColumnType::Binary(sea_orm::sea_query::BlobSize::Long).def(),
            Self::VarBinary => ColumnType::VarBinary(10u32).def(),
        }
    }
}

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.11.0...0.11.1

sea-orm - 0.11.0

Published by tyt2y3 over 1 year ago

https://www.sea-ql.org/blog/2023-02-08-whats-new-in-seaorm-0.11.0/

New Features

SeaORM Core

SeaORM CLI

SeaORM Migration

Enhancements

Upgrades

House Keeping

Bug Fixes

Breaking changes

// 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)?;
        ..
    }
}
#[async_trait::async_trait]
impl ActiveModelBehavior for ActiveModel {
    async fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>
    where
        C: ConnectionTrait,
    {
        // ...
    }

    // ...
}
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 https://github.com/SeaQL/sea-orm/pull/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

New Contributors

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.10.0...0.11.0

sea-orm - 0.11.0-rc.2

Published by tyt2y3 over 1 year ago

See 0.11.0 release notes

sea-orm - 0.11.0-rc.1

Published by tyt2y3 over 1 year ago

See 0.11.0 release notes

sea-orm - 0.10.7

Published by tyt2y3 almost 2 years ago

Bug Fixes

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.10.6...0.10.7

sea-orm - 0.10.6

Published by billy1624 almost 2 years ago

Enhancements

Bug Fixes

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.10.5...0.10.6

sea-orm - 0.10.5

Published by tyt2y3 almost 2 years ago

New Features

Bug Fixes

Enhancements

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.10.4...0.10.5

sea-orm - 0.10.4

Published by tyt2y3 almost 2 years ago

Bug Fixes

Enhancements

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.10.3...0.10.4

sea-orm - 0.10.3

Published by tyt2y3 almost 2 years ago

Bug Fixes

Enhancements

House Keeping

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.10.2...0.10.3

sea-orm - 0.10.2

Published by tyt2y3 almost 2 years ago

Enhancements

Bug Fixes

Upgrades

  • Update MSRV to 1.65

New Contributors

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.10.1...0.10.2

sea-orm - 0.10.1

Published by billy1624 almost 2 years ago

Enhancements

Bug Fixes

House Keeping

Upgrades

New Contributors

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.10.0...0.10.1

sea-orm - 0.10.0

Published by tyt2y3 almost 2 years ago

https://www.sea-ql.org/blog/2022-11-10-whats-new-in-0.10.x/

New Features

Enhancements

Bug fixes

Breaking changes

enum ColumnType {
    // then
    Enum(String, Vec<String>)

    // now
    Enum {
        /// Name of enum
        name: DynIden,
        /// Variants of enum
        variants: Vec<DynIden>,
    }
    ...
}
  • A new method array_type was added to ValueType:
impl sea_orm::sea_query::ValueType for MyType {
    fn array_type() -> sea_orm::sea_query::ArrayType {
        sea_orm::sea_query::ArrayType::TypeName
    }
    ...
}
  • ActiveEnum::name() changed return type to DynIden:
#[derive(Debug, Iden)]
#[iden = "category"]
pub struct CategoryEnum;

impl ActiveEnum for Category {
    // then
    fn name() -> String {
        "category".to_owned()
    }

    // now
    fn name() -> DynIden {
        SeaRc::new(CategoryEnum)
    }
    ...
}

House keeping

Integration

Upgrades

New Contributors

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.9.0...0.10.0

sea-orm - 0.9.3

Published by tyt2y3 about 2 years ago

Enhancements

Bug fixes

sea-orm - 0.9.2

Published by tyt2y3 about 2 years ago

Enhancements

House keeping

Notes

In this minor release, we removed time v0.1 from the dependency graph

sea-orm - 0.9.1

Published by tyt2y3 about 2 years ago

Enhancements

Bug Fixes

House keeping

sea-orm - 0.9.0

Published by tyt2y3 over 2 years ago

https://www.sea-ql.org/blog/2022-07-17-whats-new-in-0.9.0/

New Features

  • Cursor pagination (#822)
  • Custom join on conditions (#793)
  • DeriveMigrationName and sea_orm_migration::util::get_file_stem (#736)
  • FromJsonQueryResult for deserializing Json from query result (#794)

Enhancements

  • Added sqlx_logging_level to ConnectOptions (#800)
  • Added num_items_and_pages to Paginator (#768)
  • Added TryFromU64 for time (#849)
  • Added Insert::on_conflict (#791)
  • Added QuerySelect::join_as and QuerySelect::join_as_rev (#852)
  • Include column name in TryGetError::Null (#853)
  • [sea-orm-cli] Improve logging (#735)
  • [sea-orm-cli] Generate enum with numeric like variants (#588)
  • [sea-orm-cli] Allow old pending migration to be applied (#755)
  • [sea-orm-cli] Skip generating entity for ignored tables (#837)
  • [sea-orm-cli] Generate code for time crate (#724)
  • [sea-orm-cli] Add various blob column types (#850)
  • [sea-orm-cli] Generate entity files with Postgres's schema name (#422)

Upgrades

  • Upgrade clap to 3.2 (#706)
  • Upgrade time to 0.3 (#834)
  • Upgrade sqlx to 0.6 (#834)
  • Upgrade uuid to 1.0 (#834)
  • Upgrade sea-query to 0.26 (#834)
  • Upgrade sea-schema to 0.9 (#834)

House keeping

  • Refactor stream metrics (#778)

Bug Fixes

  • [sea-orm-cli] skip checking connection string for credentials (#851)

Breaking changes

  • SelectTwoMany::one() has been dropped https://github.com/SeaQL/sea-orm/pull/813, you can get (Entity, Vec<RelatedEntity>) by first querying a single model from Entity, then use [ModelTrait::find_related] on the model.
  • Feature flag revamp

    We now adopt the weak dependency syntax in Cargo. That means the flags ["sqlx-json", "sqlx-chrono", "sqlx-decimal", "sqlx-uuid", "sqlx-time"] are not needed and now removed. Instead, with-time will enable sqlx?/time only if sqlx is already enabled. As a consequence, now the features with-json, with-chrono, with-rust_decimal, with-uuid, with-time will not be enabled as a side-effects of enabling sqlx.

New Contributors

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.8.0...0.9.0

sea-orm - 0.8.0

Published by tyt2y3 over 2 years ago

https://www.sea-ql.org/blog/2022-05-15-whats-new-in-0.8.0/

New Features

Enhancements

Bug Fixes

Breaking changes

  • Migration utilities are moved from sea-schema to sea-orm repo, under a new sub-crate sea-orm-migration. sea_schema::migration::prelude should be replaced by sea_orm_migration::prelude in all migration files

Upgrades

Fixed Issues

New Contributors

Full Changelog: https://github.com/SeaQL/sea-orm/compare/0.7.1...0.8.0