SeaQL / sea-orm

🐚 An async & dynamic ORM for Rust
https://www.sea-ql.org/SeaORM/
Apache License 2.0
7.3k stars 513 forks source link

Implement FromQueryResult for tuples #1017

Closed reu closed 1 year ago

reu commented 2 years ago

Motivation

Currently sea-orm requires us to create a struct and derive a macro to be used on custom queries.

By having FromQueryResult for tuples we would be able to something like this:

let (count, max_price) = Entity::find()
  .select_only()
  .column_as(Column::Id::count(), "count")
  .column_as(Column::Price.max(), "max")
  .into_model::<(i32, Option<Decimal>)>()
  .one(&db)
  .await?
billy1624 commented 2 years ago

Hey @reu, thanks for the ideas! Actually, after some investigation, we already support select tuple results.

#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
enum QueryAs {
    CakeName,
}

let res: Vec<String> = cake::Entity::find()
    .select_only()
    .column_as(cake::Column::Name, QueryAs::CakeName)
    .into_values::<_, QueryAs>()
    .all(&db)
    .await?;

assert_eq!(
    res,
    vec!["Chocolate Forest".to_owned(), "New York Cheese".to_owned()]
);
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
enum QueryAs {
    CakeName,
    NumOfCakes,
}

let res: Vec<(String, i64)> = cake::Entity::find()
    .select_only()
    .column_as(cake::Column::Name, QueryAs::CakeName)
    .column_as(cake::Column::Id.count(), QueryAs::NumOfCakes)
    .group_by(cake::Column::Name)
    .into_values::<_, QueryAs>()
    .all(&db)
    .await?;

assert_eq!(res, vec![("Chocolate Forest".to_owned(), 2i64)]);

https://docs.rs/sea-orm/latest/sea_orm/entity/prelude/struct.Select.html#method.into_values